我有一堂课

@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;
    }
}

10-06 06:21