ReverseEngineeringStrategy is great way to affect the naming of fields (particularly xref tables that make many-to-many relationships), but it's only one piece of the puzzle. I have a blog entry on controlling Hibernate reverse engineering. I've since turned those notes into a script and should probably make a new blog entry for the script, but here's the old one:
http://glenpeterson.blogspot.com/2008/07/mysql-data-types-and-naming-for-use.htmlHere's an example ReverseEngineeringStrategy implementation which I actually use. The way the API is structured, there were going to be a lot of checks to see if a given field was the one I wanted. Instead of checking each field individually, I just concatenate all the information into a string and do a string comparison. About half of the code in this example is the concatenation, the rest are overridden methods
I hope this helps:
Code:
public class RevEngStrategy extends DelegatingReverseEngineeringStrategy {
public RevEngStrategy(ReverseEngineeringStrategy delegate) {
super(delegate);
}
/**
Concetanates a list of column names using a hyphen as a separator.
*/
private static String figureColName(List<Column> cols) {
if (cols == null) {
return null;
} else if (cols.size() < 1) {
return "";
} else if (cols.size() == 1) {
return cols.get(0).getName();
} else {
StringBuilder sB = new StringBuilder();
boolean isFirst = true;
for (Column col : cols) {
if (isFirst) {
isFirst = false;
} else {
sB.append("-");
}
sB.append(col.getName());
}
return sB.toString();
}
}
private static String concatColInfo(String keyname,
TableIdentifier fromTable,
String fromCol,
TableIdentifier referencedTable,
String refCol,
boolean uniqueRef) {
StringBuilder sB = new StringBuilder();
sB.append(keyname);
sB.append("|");
sB.append(fromTable.getName());
sB.append("|");
sB.append(fromCol);
sB.append("|");
sB.append(referencedTable.getName());
sB.append("|");
sB.append(refCol);
sB.append("|");
if (uniqueRef) {
sB.append("1");
} else {
sB.append("0");
}
return sB.toString();
}
@Override
public String foreignKeyToCollectionName(String keyname,
TableIdentifier fromTable,
List fromColumns,
TableIdentifier refTable,
List refColumns,
boolean uniqueRef) {
// Concatenate a hyphen-separated columnName string from the list Hibernate gives us.
String fromCol = figureColName( (List<Column>) fromColumns);
String refCol = figureColName( (List<Column>) refColumns);
// Concatenate all column info using pipes as separators
String val = concatColInfo(keyname, fromTable, fromCol, refTable, refCol, uniqueRef);
String ret = null;
// Check if it's the column we want
// Instead of "subsets" I want "thisEntitysSubsets".
// Because an entity can have subsets and also belong to another
// entity's subsets and I want to be clear which is which!
if ("m_subset_fk_entity|metric_subset|entity_id|entity|id|1".equals(val) ) {
System.out.println("******* thisEntitysSubsets *******");
ret = "thisEntitysSubsets";
} else {
ret = super.foreignKeyToCollectionName(keyname, fromTable, fromColumns, refTable, refColumns, uniqueRef);
}
System.out.println("fk2Coll: " + val + ": " + ret);
return ret;
}
public String foreignKeyToEntityName(String keyname,
TableIdentifier fromTable,
List fromCols,
TableIdentifier refTable,
List refCols,
boolean uniqueRef)
{
String fromCol = figureColName( (List<Column>) fromCols);
String refCol = figureColName( (List<Column>) refCols);
String val = concatColInfo(keyname, fromTable, fromCol, refTable, refCol, uniqueRef);
String ret = null;
// I want to call last modifiers, "lastModifier" not "UserByLastModifierId"
// Similarly, I want "owner" not "UserByOwnerId"
// And I want to make this change to every table.
if ( "last_modifier_id".equals(fromCol) &&
"user".equals(refTable.getName()) &&
"id".equals(refCol) &&
uniqueRef &&
keyname.endsWith("fk_modifier") ) {
System.out.println("******* lastModifier *******");
ret = "lastModifier";
} else if ( "owner_id".equals(fromCol) &&
"user".equals(refTable.getName()) &&
"id".equals(refCol) &&
!"sc_metric".equals(fromTable.getName()) &&
!uniqueRef &&
keyname.endsWith("fk_owner") ) {
System.out.println("******* owner *******");
ret = "owner";
} else {
// Accept default name
ret = super.foreignKeyToEntityName(keyname, fromTable, fromCols, refTable, refCols, uniqueRef);
}
System.out.println("fk2Ent: " + val + ": " + ret);
return ret;
}
private static String figureForeignKeyName(ForeignKey fk) {
StringBuilder sB = new StringBuilder(fk.getTable().getName());
sB.append(",");
sB.append(figureColName( (List<Column>) fk.getColumns()) );
sB.append(",");
sB.append(figureColName( (List<Column>) fk.getReferencedColumns() ));
sB.append(",");
sB.append(fk.getName());
return sB.toString();
}
public String foreignKeyToManyToManyName(ForeignKey fromKey,
TableIdentifier middleTable,
ForeignKey toKey,
boolean uniqueRef)
{
StringBuilder sB = new StringBuilder();
sB.append(figureForeignKeyName(fromKey));
sB.append("|");
sB.append(middleTable.getName());
sB.append("|");
sB.append(figureForeignKeyName(toKey));
sB.append("|");
if (uniqueRef) {
sB.append("1");
} else {
sB.append("0");
}
String val = sB.toString();
String ret = null;
// Instead of "subsets1" I want "subsetsThisEntityBelongsTo"
// Because an entity can have subsets and also belong to another
// entity's subsets and I want to be clear which is which!
if ("m_subset_entity_xref,entity_id,id,m_subset_ent_fk_ent|m_subset_entity_xref|m_subset_entity_xref,m_subset_id,id,m_subset_ent_fk_metric_subset|1"
.equals(val)) {
ret = "subsetsThisEntityBelongsTo";
} else {
// Accept default name
ret = super.foreignKeyToManyToManyName(fromKey, middleTable, toKey, uniqueRef);
}
System.out.println("fk_many: " + val + " Becomes: " + ret);
return ret;
}
}