[#2043] Remove generated navigation methods
This commit is contained in:
parent
5635339388
commit
e71d9444c2
@ -47,7 +47,6 @@ abstract class AbstractGenerator implements Generator {
|
||||
|
||||
boolean generateDeprecated = true;
|
||||
boolean generateRelations = true;
|
||||
boolean generateNavigationMethods = true;
|
||||
boolean generateInstanceFields = true;
|
||||
boolean generateGeneratedAnnotation = true;
|
||||
boolean generateRecords = true;
|
||||
@ -95,16 +94,6 @@ abstract class AbstractGenerator implements Generator {
|
||||
return generateInstanceFields;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generateNavigationMethods() {
|
||||
return generateNavigationMethods;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGenerateNavigationMethods(boolean generateNavigationMethods) {
|
||||
this.generateNavigationMethods = generateNavigationMethods;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGenerateInstanceFields(boolean generateInstanceFields) {
|
||||
this.generateInstanceFields = generateInstanceFields;
|
||||
|
||||
@ -353,8 +353,6 @@ public class GenerationTool {
|
||||
g.setGenerate(new Generate());
|
||||
if (g.getGenerate().isRelations() != null)
|
||||
generator.setGenerateRelations(g.getGenerate().isRelations());
|
||||
if (g.getGenerate().isNavigationMethods() != null)
|
||||
generator.setGenerateNavigationMethods(g.getGenerate().isNavigationMethods());
|
||||
if (g.getGenerate().isDeprecated() != null)
|
||||
generator.setGenerateDeprecated(g.getGenerate().isDeprecated());
|
||||
if (g.getGenerate().isInstanceFields() != null)
|
||||
|
||||
@ -80,16 +80,6 @@ public interface Generator {
|
||||
*/
|
||||
void setGenerateRelations(boolean generateRelations);
|
||||
|
||||
/**
|
||||
* Whether foreign key navigation methods should be generated
|
||||
*/
|
||||
boolean generateNavigationMethods();
|
||||
|
||||
/**
|
||||
* Whether foreign key navigation methods should be generated
|
||||
*/
|
||||
void setGenerateNavigationMethods(boolean generateNavigationMethods);
|
||||
|
||||
/**
|
||||
* Whether instance fields should be generated (as opposed to static fields)
|
||||
*/
|
||||
|
||||
@ -44,9 +44,7 @@ import java.lang.reflect.TypeVariable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jooq.AggregateFunction;
|
||||
import org.jooq.Configuration;
|
||||
@ -58,7 +56,6 @@ import org.jooq.ForeignKey;
|
||||
import org.jooq.Identity;
|
||||
import org.jooq.Parameter;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.Result;
|
||||
import org.jooq.Row;
|
||||
import org.jooq.Sequence;
|
||||
import org.jooq.Table;
|
||||
@ -147,7 +144,6 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
log.info(" instance fields", generateInstanceFields());
|
||||
log.info(" JPA annotations", generateJPAAnnotations());
|
||||
log.info(" validation annotations", generateValidationAnnotations());
|
||||
log.info(" navigation methods", generateNavigationMethods());
|
||||
log.info(" records", generateRecords()
|
||||
+ ((!generateRecords && generateDaos) ? " (forced to true because of <daos/>)" : ""));
|
||||
log.info(" pojos", generatePojos()
|
||||
@ -530,14 +526,6 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
out.tab(1).println("}");
|
||||
}
|
||||
|
||||
if (generateRelations() && generateNavigationMethods()) {
|
||||
out.tab(1).header("Foreign key navigation methods");
|
||||
|
||||
for (ColumnDefinition column : table.getColumns()) {
|
||||
printNavigateMethods(out, column);
|
||||
}
|
||||
}
|
||||
|
||||
if (generateRelations() && key != null) {
|
||||
int keyDegree = key.getKeyColumns().size();
|
||||
|
||||
@ -2079,155 +2067,6 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
out.tab(1).println("public static final %s %s = new %s();", className, identifier, className);
|
||||
}
|
||||
|
||||
protected void printNavigateMethods(JavaWriter out, ColumnDefinition column) {
|
||||
List<UniqueKeyDefinition> uniqueKeys = column.getUniqueKeys();
|
||||
|
||||
// Print references from this column's unique keys to all
|
||||
// corresponding foreign keys.
|
||||
|
||||
// e.g. in TAuthorRecord, print getTBooks()
|
||||
// -----------------------------------------------------------------
|
||||
Set<String> fetchMethodNames = new HashSet<String>();
|
||||
for (UniqueKeyDefinition uniqueKey : uniqueKeys) {
|
||||
if (out.printOnlyOnce(uniqueKey)) {
|
||||
for (ForeignKeyDefinition foreignKey : uniqueKey.getForeignKeys()) {
|
||||
printFetchFKList(out, foreignKey, fetchMethodNames);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Print references from this foreign key to its related primary key
|
||||
// E.g. in TBookRecord print getTAuthor()
|
||||
// -----------------------------------------------------------------
|
||||
for (ForeignKeyDefinition foreignKey : column.getForeignKeys()) {
|
||||
if (out.printOnlyOnce(foreignKey)) {
|
||||
printFetchFK(out, column, foreignKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void printFetchFK(JavaWriter out, ColumnDefinition column, ForeignKeyDefinition foreignKey) {
|
||||
|
||||
// #64 - If the foreign key does not match the referenced key, it
|
||||
// is most likely because it references a non-primary unique key
|
||||
// Skip code generation for this foreign key
|
||||
|
||||
// #69 - Should resolve this issue more thoroughly.
|
||||
if (foreignKey.getReferencedColumns().size() != foreignKey.getKeyColumns().size()) {
|
||||
log.warn("Foreign key mismatch", foreignKey.getName() + " does not match its primary key! No code is generated for this key. See trac tickets #64 and #69");
|
||||
return;
|
||||
}
|
||||
|
||||
final TableDefinition referenced = foreignKey.getReferencedTable();
|
||||
final TableDefinition referencing = foreignKey.getKeyTable();
|
||||
|
||||
final String referencedId = getStrategy().getFullJavaIdentifier(referenced);
|
||||
final String referencedType = getStrategy().getFullJavaClassName(referenced, Mode.RECORD);
|
||||
final String referencedClassName = getStrategy().getJavaClassName(referenced);
|
||||
|
||||
// [#350] - Disambiguate multiple foreign keys referencing
|
||||
// the same table
|
||||
List<String> disambiguation = list(foreignKey.countSimilarReferences() > 1
|
||||
? getStrategy().getJavaClassName(column)
|
||||
: null);
|
||||
|
||||
out.tab(1).javadoc("Fetch a record from <code>%s</code> referenced from <code>%s</code> through <code>%s</code>",
|
||||
referenced.getQualifiedOutputName(),
|
||||
referencing.getQualifiedOutputName(),
|
||||
foreignKey.getQualifiedOutputName());
|
||||
out.tab(1).println("public %s fetch%s[[before=By][%s]]() {", referencedType, referencedClassName, disambiguation);
|
||||
out.tab(2).println("return create()");
|
||||
out.tab(3).println(".selectFrom(%s)", referencedId);
|
||||
|
||||
String connector = "where";
|
||||
for (int i = 0; i < foreignKey.getReferencedColumns().size(); i++) {
|
||||
final String ukId = getStrategy().getFullJavaIdentifier(foreignKey.getReferencedColumns().get(i));
|
||||
final String fkId = getStrategy().getFullJavaIdentifier(foreignKey.getKeyColumns().get(i));
|
||||
|
||||
// Convert foreign key value, if there is a type mismatch
|
||||
DataTypeDefinition foreignType = foreignKey.getKeyColumns().get(i).getType();
|
||||
DataTypeDefinition primaryType = foreignKey.getReferencedColumns().get(i).getType();
|
||||
|
||||
List<String> conversion = list(!match(foreignType, primaryType)
|
||||
? getSimpleJavaType(foreignKey.getReferencedColumns().get(i).getType())
|
||||
: null);
|
||||
|
||||
out.tab(3).println(".%s(%s.equal(getValue(%s[[before=, ][after=.class][%s]])))", connector, ukId, fkId, conversion);
|
||||
connector = "and";
|
||||
}
|
||||
|
||||
out.println("\t\t\t.fetchOne();");
|
||||
out.println("\t}");
|
||||
}
|
||||
|
||||
protected void printFetchFKList(JavaWriter out, ForeignKeyDefinition foreignKey, Set<String> fetchMethodNames) {
|
||||
// [#64] - If the foreign key does not match the referenced key, it
|
||||
// is most likely because it references a non-primary unique key
|
||||
// Skip code generation for this foreign key
|
||||
|
||||
|
||||
// [#69] - Should resolve this issue more thoroughly.
|
||||
if (foreignKey.getReferencedColumns().size() != foreignKey.getKeyColumns().size()) {
|
||||
log.warn("Foreign key mismatch", foreignKey.getName() + " does not match its primary key! No code is generated for this key. See trac tickets #64 and #69");
|
||||
return;
|
||||
}
|
||||
|
||||
final TableDefinition referencing = foreignKey.getKeyTable();
|
||||
final TableDefinition referenced = foreignKey.getReferencedTable();
|
||||
final UniqueKeyDefinition uniqueKey = foreignKey.getReferencedKey();
|
||||
|
||||
final String referencingType = getStrategy().getFullJavaClassName(referencing, Mode.RECORD);
|
||||
final String referencingId = getStrategy().getFullJavaIdentifier(referencing);
|
||||
final StringBuilder method = new StringBuilder();
|
||||
|
||||
method.append("fetch");
|
||||
method.append(getStrategy().getJavaClassName(referencing));
|
||||
|
||||
// [#352] - Disambiguate foreign key navigation directions
|
||||
method.append("List");
|
||||
|
||||
// [#350] - Disambiguate multiple foreign keys referencing
|
||||
// the same table
|
||||
if (foreignKey.countSimilarReferences() > 1) {
|
||||
method.append("By");
|
||||
method.append(getStrategy().getJavaClassName(foreignKey.getKeyColumns().get(0)));
|
||||
}
|
||||
|
||||
// [#1270] - Disambiguate identical foreign keys
|
||||
if (fetchMethodNames.contains(method.toString())) {
|
||||
log.warn("Duplicate foreign key", foreignKey.getName() + " has the same properties as another foreign key! No code is generated for this key. See trac ticket #1270");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
fetchMethodNames.add(method.toString());
|
||||
}
|
||||
|
||||
out.tab(1).javadoc("Fetch a list of <code>%s</code> referencing this <code>%s</code>", referencing.getQualifiedOutputName(), referenced.getQualifiedOutputName());
|
||||
out.tab(1).println("public %s<%s> %s() {", Result.class, referencingType, method);
|
||||
out.tab(2).println("return create()");
|
||||
out.tab(3).println(".selectFrom(%s)", referencingId);
|
||||
|
||||
String connector = "where";
|
||||
for (int i = 0; i < foreignKey.getReferencedColumns().size(); i++) {
|
||||
final String fkId = getStrategy().getFullJavaIdentifier(foreignKey.getKeyColumns().get(i));
|
||||
final String ukId = getStrategy().getFullJavaIdentifier(uniqueKey.getKeyColumns().get(i));
|
||||
|
||||
// Convert foreign key value, if there is a type mismatch
|
||||
DataTypeDefinition foreignType = foreignKey.getKeyColumns().get(i).getType();
|
||||
DataTypeDefinition primaryType = uniqueKey.getKeyColumns().get(i).getType();
|
||||
|
||||
List<String> conversion = list(!match(foreignType, primaryType)
|
||||
? getSimpleJavaType(foreignKey.getKeyColumns().get(i).getType())
|
||||
: null);
|
||||
|
||||
out.tab(3).println(".%s(%s.equal(getValue(%s[[before=, ][after=.class][%s]])))", connector, fkId, ukId, conversion);
|
||||
connector = "and";
|
||||
}
|
||||
|
||||
out.tab(3).println(".fetch();");
|
||||
out.tab(1).println("}");
|
||||
}
|
||||
|
||||
protected void printClassJavadoc(JavaWriter out, Definition definition) {
|
||||
printClassJavadoc(out, definition.getComment());
|
||||
}
|
||||
|
||||
@ -2,8 +2,6 @@ package org.jooq.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
@ -18,12 +16,8 @@ public class JavaWriter extends GeneratorWriter<JavaWriter> {
|
||||
|
||||
private static final String SERIAL_STATEMENT = "__SERIAL_STATEMENT__";
|
||||
|
||||
private final Set<Object> alreadyPrinted;
|
||||
|
||||
public JavaWriter(File file) {
|
||||
super(file);
|
||||
|
||||
this.alreadyPrinted = new HashSet<Object>();
|
||||
}
|
||||
|
||||
public JavaWriter print(Class<?> clazz) {
|
||||
@ -75,15 +69,6 @@ public class JavaWriter extends GeneratorWriter<JavaWriter> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean printOnlyOnce(Object object) {
|
||||
if (!alreadyPrinted.contains(object)) {
|
||||
alreadyPrinted.add(object);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void printSerial() {
|
||||
println();
|
||||
println("\tprivate static final long serialVersionUID = %s;", SERIAL_STATEMENT);
|
||||
|
||||
@ -296,13 +296,6 @@
|
||||
-->
|
||||
<element name="relations" type="boolean" default="true" minOccurs="0" maxOccurs="1" />
|
||||
|
||||
<!--
|
||||
Generate navigation methods to navigate foreign key relationships
|
||||
directly from Record classes. This is only relevant if relations
|
||||
is set to true, too
|
||||
-->
|
||||
<element name="navigationMethods" type="boolean" default="true" minOccurs="0" maxOccurs="1" />
|
||||
|
||||
<!-- Generate deprecated code for backwards compatibility -->
|
||||
<element name="deprecated" type="boolean" default="true" minOccurs="0" maxOccurs="1" />
|
||||
|
||||
|
||||
@ -47,17 +47,12 @@ import static org.jooq.impl.Factory.table;
|
||||
|
||||
import java.sql.Date;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.jooq.Field;
|
||||
import org.jooq.InsertQuery;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.Record1;
|
||||
import org.jooq.Record2;
|
||||
import org.jooq.Record3;
|
||||
@ -235,68 +230,6 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T725,
|
||||
assertEquals(null, create().fetchOne(TAuthor(), TAuthor_FIRST_NAME().equal("Erich")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRelations() throws Exception {
|
||||
if (getDialect() == SQLDialect.SQLITE) {
|
||||
log.info("SKIPPING", "referentials test");
|
||||
return;
|
||||
}
|
||||
|
||||
jOOQAbstractTest.reset = false;
|
||||
|
||||
// Get the book 1984
|
||||
B book1984 = create().fetchOne(TBook(), TBook_TITLE().equal("1984"));
|
||||
|
||||
// Navigate to the book's author
|
||||
Record authorOrwell = (Record) invoke(book1984, "fetchTAuthorByAuthorId");
|
||||
assertEquals("Orwell", authorOrwell.getValue(TAuthor_LAST_NAME()));
|
||||
|
||||
// Navigate back to the author's books
|
||||
List<?> books1 = (List<?>) invoke(authorOrwell, "fetchTBookListByAuthorId");
|
||||
assertEquals(2, books1.size());
|
||||
|
||||
// Navigate through m:n relationships of books
|
||||
List<Object> booksToBookStores = new ArrayList<Object>();
|
||||
for (Object b : books1) {
|
||||
booksToBookStores.addAll((List<?>) invoke(b, "fetchTBookToBookStoreList"));
|
||||
}
|
||||
assertEquals(3, booksToBookStores.size());
|
||||
|
||||
// Navigate to book stores
|
||||
Set<String> bookStoreNames = new TreeSet<String>();
|
||||
List<Object> bookStores = new ArrayList<Object>();
|
||||
for (Object b : booksToBookStores) {
|
||||
Object store = invoke(b, "fetchTBookStore");
|
||||
bookStores.add(store);
|
||||
bookStoreNames.add((String) invoke(store, "getName"));
|
||||
}
|
||||
assertEquals(Arrays.asList("Ex Libris", "Orell Füssli"), new ArrayList<String>(bookStoreNames));
|
||||
|
||||
// Navigate through m:n relationships of book stores
|
||||
booksToBookStores = new ArrayList<Object>();
|
||||
for (Object b : bookStores) {
|
||||
booksToBookStores.addAll((List<?>) invoke(b, "fetchTBookToBookStoreList"));
|
||||
}
|
||||
|
||||
// Navigate back to books
|
||||
Set<String> book2Names = new TreeSet<String>();
|
||||
List<Object> books2 = new ArrayList<Object>();
|
||||
for (Object b : booksToBookStores) {
|
||||
Object book = invoke(b, "fetchTBook");
|
||||
books2.add(book);
|
||||
book2Names.add((String) invoke(book, "getTitle"));
|
||||
}
|
||||
assertEquals(Arrays.asList("1984", "Animal Farm", "O Alquimista"), new ArrayList<String>(book2Names));
|
||||
|
||||
// Navigate back to authors
|
||||
Set<String> authorNames = new TreeSet<String>();
|
||||
for (Object b : books2) {
|
||||
Object author = invoke(b, "fetchTAuthorByAuthorId");
|
||||
authorNames.add((String) invoke(author, "getLastName"));
|
||||
}
|
||||
assertEquals(Arrays.asList("Coelho", "Orwell"), new ArrayList<String>(authorNames));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdatablesCopy() throws Exception {
|
||||
if (TTriggers() == null) {
|
||||
|
||||
@ -145,7 +145,7 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T725,
|
||||
assertEquals(sequence, schema.getSequence(sequence.getName()));
|
||||
}
|
||||
|
||||
int tables = 17;
|
||||
int tables = 18;
|
||||
|
||||
// The additional T_DIRECTORY table for recursive queries
|
||||
if (supportsRecursiveQueries()) {
|
||||
|
||||
@ -9209,6 +9209,8 @@ for (Record record : create().select(
|
||||
<li>Various API changes have been done</li>
|
||||
</ul>
|
||||
|
||||
<h3>No more navigation methods and "foreign key setters"</h3>
|
||||
|
||||
<h3>Object renames</h3>
|
||||
<ul>
|
||||
<li>jOOU</li>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user