我有一堂课
@MappedSuperclass
public abstract class MyAbstractProperty <T extends Object>{
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private Long id;
@Column(name="defaultValue")
protected T defaultValue;
//...
}
这是
class MyLongProperty extends MyAbstractProperty<Long>{}
等子类的基础。这很好。当我想将Text存储在类
class MyStringProperty extends MyAbstractProperty<String>{}
中时,就会出现问题。我了解到,默认情况下,休眠状态仅存储最多255个字符的字符串(请参见:JPA: "Data too long for column" does not change)。因此,我的
defaultValue
需要一个附加的注释,例如:@Entity
class MyStringProperty extends MyAbstractProperty<String>{
@Type(type="org.hibernate.type.StringClobType")
@Column(name="defaultValue")
protected String defaultValue; // problem since defaultValue is already defined in MyAbstractProperty<>.
}
由于默认值已在
MyAbstractProperty
中定义,如何确保这一点?我认为将类型注释移至MyAbstractProperty
是不可行的,因为这可能会对诸如MyLongProperty
的其他类产生副作用。例如,当我在
@Lob
中设置MyAbstractProperty
时,MyStringProperty
的SQL定义包括DEFAULTVALUE BLOB(255)
而不是DEFAULTVALUE BIGINT
。另一个问题:将列定义为文本数据似乎有不同的选择(例如
@Type(type="org.hibernate.type.StringClobType")
,@Lob
)。这些选项的主要区别在哪里?什么最好的。 (我的主数据库是HyperSQL,但我也针对SQLite,MariaDB和MySQL)。编辑
根据最近的反馈,解决方案似乎是抽象的获取器/设置器。我必须检查我的代码对此有何影响。
我有一个备选方案-尚未完成-可能会导致我的代码修改较少。是否可以定义一个类
class MyText extendes String;
例如
MyText
的所有实例都自动存储为@Lob
?比起我只需要将
MyAbstractProperty<String>
修改为MyAbstractProperty<MyText>
。 最佳答案
您可以在超类中仅保留一个抽象的getter,并在子类中定义该字段:
@MappedSuperclass
public abstract class MyAbstractProperty<T extends Object>{
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private Long id;
public abstract T getDefaultValue();
}
@Entity
class MyStringProperty extends MyAbstractProperty<String>{
@Type(type="org.hibernate.type.StringClobType")
@Column(name="defaultValue")
protected String defaultValue;
@Override
public String getDefaultValue() {
return defaultValue;
}
}
为了避免在不需要特殊处理的所有其他情况下创建样板,您可以简单地创建另一个包含默认映射的抽象类,然后从中扩展其他实体:
@MappedSuperclass
public abstract class MyDefaultProperty<T> extends MyAbstractProperty<T extends Object> {
@Column(name="defaultValue")
protected T defaultValue;
@Override
public T getDefaultValue() {
return defaultValue;
}
}