Java @Enumerated@ElementCollection的命名策略
在Java应用程序中,我使用的枚举集合如下:Java @Enumerated@ElementCollection的命名策略,java,hibernate,Java,Hibernate,在Java应用程序中,我使用的枚举集合如下: @ElementCollection @Enumerated(EnumType.ORDINAL) protected Set<Tag> tags = new TreeSet<>(); @ElementCollection @枚举(EnumType.ORDINAL) 受保护的集合标记=新树集(); 然而,这个定义是在@MappedSuperClass中给出的,因此我不能在@JoinTable中定义名称,因为名称会在子类中发生
@ElementCollection
@Enumerated(EnumType.ORDINAL)
protected Set<Tag> tags = new TreeSet<>();
@ElementCollection
@枚举(EnumType.ORDINAL)
受保护的集合标记=新树集();
然而,这个定义是在@MappedSuperClass
中给出的,因此我不能在@JoinTable
中定义名称,因为名称会在子类中发生冲突。我的问题是默认的hibernate命名策略被忽略。例如,对于继承的类Event
而不是名为Event\u标签的表,hibernate尝试使用Event\u标签
,而不是字段Event\u id
,它尝试使用Event\u id
。在我看来,Hibernate完全忽略了命名策略,只使用实体名称而不做任何更改
如何强制它使用默认命名策略?默认命名策略似乎无法处理这些问题,您需要实现自己的命名策略。例如:
public class NamingPolicy implements NamingStrategy, Serializable {
@Override
public String classToTableName(String className) {
return StringHelper.unqualify(className).toLowerCase();
}
@Override
public String propertyToColumnName(String propertyName) {
return StringHelper.unqualify(propertyName);
}
public String singularize(String propertyName) {
if (propertyName != null && propertyName.endsWith("s")) {
propertyName = propertyName.substring(0, propertyName.length() - 1);
}
return propertyName;
}
@Override
public String tableName(String tableName) {
return tableName;
}
@Override
public String columnName(String columnName) {
return columnName;
}
@Override
public String collectionTableName(
String ownerEntity, String ownerEntityTable, String associatedEntity,
String associatedEntityTable, String propertyName) {
return classToTableName(ownerEntityTable) + "_" +
or(associatedEntityTable, singularize(propertyName));
}
@Override
public String joinKeyColumnName(String joinedColumn, String joinedTable) {
return columnName(joinedColumn);
}
@Override
public String foreignKeyColumnName(
String propertyName, String propertyEntityName,
String propertyTableName, String referencedColumnName) {
String header = propertyName != null ? propertyName : propertyTableName;
if (header == null) {
throw new AssertionFailure("NamingStrategy not properly filled");
}
return classToTableName(header) + "_" + referencedColumnName;
}
@Override
public String logicalColumnName(String columnName, String propertyName) {
return StringHelper.isNotEmpty(columnName)
? columnName : StringHelper.unqualify(propertyName);
}
@Override
public String logicalCollectionTableName(
String tableName, String ownerEntityTable, String associatedEntityTable, String propertyName) {
if (tableName != null) {
return tableName;
} else {
return tableName(ownerEntityTable) + "_" + (associatedEntityTable != null
? associatedEntityTable
: singularize(propertyName));
}
}
@Override
public String logicalCollectionColumnName(
String columnName, String propertyName, String referencedColumn) {
return StringHelper.isNotEmpty(columnName)
? columnName
: classToTableName(propertyName) + "_" + singularize(referencedColumn);
}
}
作为一个无关的注释,如果元素类型是枚举,请始终使用EnumSet
;它很小而且速度非常快。我不想使用EnumSet,因为这个Enum的大小是1000,而且我通常在集合中只有几个元素。如果您检查实现,您将看到它为所有元素分配内存,这在我的例子中是不需要的。