2017-02-27 141 views
1

我有一个类休眠:附加注释列从继承

@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 MyStringProperty extends MyAbstractProperty<String>{}中时,问题就出现了。

我已经了解到,每个默认存储区的hibernate只存储最多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等其他类有副作用。

例如,当我在MyAbstractProperty设定@LobMyStringProperty SQL定义包括DEFAULTVALUE BLOB(255)代替DEFAULTVALUE BIGINT

附加问题:将列定义为文本数据似乎有不同的选项(例如@Type(type="org.hibernate.type.StringClobType")@Lob)这些选项中的大写差异在哪里。最好采取什么。 (我的主数据库是HyperSQL,但我也针对SQLite,MariaDB和MySQL)。

编辑

基于这似乎是解决办法可能是抽象的getter/setter方法最近反馈。我必须检查我的代码对此有什么影响。

我有一个替代 - 没有完成 - 的想法,这可能会导致我的代码更少修改。是否有可能定义一个类

class MyText extendes String; 

如的MyText所有实例都将自动存储为@Lob? 比我只需要修改MyAbstractProperty<String>MyAbstractProperty<MyText>

+0

我认为你需要遵循继承策略之一,所以请阅读这篇文章http://www.thejavageek.com/2014/ 05/14/jpa-single-table-inheritance-example/ –

+0

因此,大多数情况下,您需要在您的抽象类中使用@Inheritance注释和您想要的策略 –

+0

另外我认为您应该从MyStringProperty中移除defaultValue,因为它已经在超类中并移动了@Type(type =“org.hibernate.type .StringClobType“)到MyAbstractProperty –

回答

1

你可以留在超只是一个抽象的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; 
    } 
} 
+0

谢谢你Dragan Bozanovic为你的答案。这似乎有可能通过我的代码中的一些重构将是必需的。请检查我的问题的编辑。也许这个想法可能导致更简单的解决方案? – BerndGit

+0

@BerndGit你不能从'String'扩展,它是一个最终的类。即使可以,效果也是一样的,因为您需要将'@ Lob'注释放在包含类中的MyText类型的字段上。 –