Hibernate:继承对 Column 的附加注释
Hibernate: Additional annotation to Column from inheritance
我有一个class
@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>{}
这样的子 class 的基础。
这很好用。当我想将文本存储在 class 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
是可行的,因为这可能会对其他 class 产生副作用,例如 MyLongProperty
.
例如,当我在 MyAbstractProperty
中设置 @Lob
时,MyStringProperty
的 SQL 定义包括 DEFAULTVALUE BLOB(255)
而不是 DEFAULTVALUE BIGINT
。
附加问题:将列定义为文本数据似乎有不同的选项(例如@Type(type="org.hibernate.type.StringClobType")
、@Lob
)这些选项的主要区别在哪里。带什么最好。 (我的主要数据库是 HyperSQL,但我也针对 SQLite、MariaDB 和 MySQL)。
编辑
根据最近的反馈,解决方案似乎很抽象 getters/setter。我必须检查这对我的代码有什么影响。
我有一个替代方案 - 未完成 - 想法,它可能会减少我的代码修改。是否可以定义一个 class
class MyText extendes String;
例如 MyText
的所有实例都自动存储为 @Lob
?
比我只需要修改 MyAbstractProperty<String>
到 MyAbstractProperty<MyText>
.
你可以在 superclass 中只留下一个抽象 getter,并在 subclasses 中定义字段:
@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;
}
}
为了避免所有其他不需要特殊处理的情况的样板,您可以简单地创建另一个包含默认映射的抽象 class,然后从中扩展其他实体:
@MappedSuperclass
public abstract class MyDefaultProperty<T> extends MyAbstractProperty<T extends Object> {
@Column(name="defaultValue")
protected T defaultValue;
@Override
public T getDefaultValue() {
return defaultValue;
}
}
我有一个class
@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>{}
这样的子 class 的基础。
这很好用。当我想将文本存储在 class 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
是可行的,因为这可能会对其他 class 产生副作用,例如 MyLongProperty
.
例如,当我在 MyAbstractProperty
中设置 @Lob
时,MyStringProperty
的 SQL 定义包括 DEFAULTVALUE BLOB(255)
而不是 DEFAULTVALUE BIGINT
。
附加问题:将列定义为文本数据似乎有不同的选项(例如@Type(type="org.hibernate.type.StringClobType")
、@Lob
)这些选项的主要区别在哪里。带什么最好。 (我的主要数据库是 HyperSQL,但我也针对 SQLite、MariaDB 和 MySQL)。
编辑
根据最近的反馈,解决方案似乎很抽象 getters/setter。我必须检查这对我的代码有什么影响。
我有一个替代方案 - 未完成 - 想法,它可能会减少我的代码修改。是否可以定义一个 class
class MyText extendes String;
例如 MyText
的所有实例都自动存储为 @Lob
?
比我只需要修改 MyAbstractProperty<String>
到 MyAbstractProperty<MyText>
.
你可以在 superclass 中只留下一个抽象 getter,并在 subclasses 中定义字段:
@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;
}
}
为了避免所有其他不需要特殊处理的情况的样板,您可以简单地创建另一个包含默认映射的抽象 class,然后从中扩展其他实体:
@MappedSuperclass
public abstract class MyDefaultProperty<T> extends MyAbstractProperty<T extends Object> {
@Column(name="defaultValue")
protected T defaultValue;
@Override
public T getDefaultValue() {
return defaultValue;
}
}