2017-07-14 88 views
1

時,我有以下兩類:休眠未綁定類型,沒有明確的目標實體使用通用

@Entity 
@Table(name = "criteria") 
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) 
@DiscriminatorColumn(name = AbstractCriteria.TYPE, discriminatorType = DiscriminatorType.STRING) 
public abstract class AbstractCriteria<T> implements Serializable { 

    public static final String TYPE = "type"; 

    ... 
    @Column(name = "clazz") private Class<T> clazz; 
    ... 

    protected AbstractCriteria(Class<T> clazz) { 
     this.clazz = Preconditions.checkNotNull(clazz); 
    } 
    ... 

    public abstract Predicate<T> evaluate(T value); 
} 

@Entity 
@DiscriminatorValue(CriteriaType.Values.DATETIME_IS_BETWEEN) 
public class DateTimeIsBetweenCriteria extends AbstractCriteria<DateTime> { 
    ... 
    public DateTimeIsBetweenCriteria() { 
     super(DateTime.class); 
    } 
    ... 


    @Override 
    public Predicate<DateTime> evaluate(DateTime value) { 
     ... 
    } 
} 

當我試圖挽救DateTimeIsBetweenCriteria類的實例,我得到這個異常:

Exception in thread "main" org.hibernate.AnnotationException: 
Property ...AbstractCriteria.clazz has an unbound type and no explicit target entity. 
Resolve this Generic usage issue or set an explicit target attribute (eg @OneToMany(target=) or use an explicit @Type 

我需要clazzAbstractCriteria的方法,以及T可以是字符串,日期時間,布爾等

我THI但是如果我這樣做了,我仍然必須有另一列來確定要保存哪些條件,以便在從數據庫中加載條件時,我知道它是哪種類型的條件。我認爲這有點不好。

任何想法如何解決該異常而不改變我的設計?

我非常感謝你的時間。

回答

0

我已經改變了我對執行不使用參數化類型:

@Entity 
@Table(name = "criteria") 
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) 
@DiscriminatorColumn(name = AbstractCriteria.TYPE, discriminatorType = DiscriminatorType.STRING) 
public abstract class AbstractCriteria implements Serializable { 

    public static final String TYPE = "type"; 

    ... 
    @Column(name = "clazz") private Class clazz; 
    ... 

    protected AbstractCriteria(Class clazz) { 
    this.clazz = Preconditions.checkNotNull(clazz); 
    } 
    ... 

    public abstract Predicate evaluate(Object value); 
} 

@Entity 
@DiscriminatorValue(CriteriaType.Values.DATETIME_IS_BETWEEN) 
public class DateTimeIsBetweenCriteria extends AbstractCriteria { 
    ... 
    public DateTimeIsBetweenCriteria() { 
    super(DateTime.class); 
    } 
    ... 


    @Override 
    public Predicate evaluate(Object value) { 
    if (value instanceof DateTime) { 
     // do evaluation and return here. 
    } else { 
     throw new UserDefinedException("..."); 
    } 
    } 
} 
0

就泛型而言,你是正確的,但你試圖堅持一類「類」類。數據庫沒有可以直接映射到的數據類型(因此你的錯誤),我能想到的最接近的是使用字符串作爲類名;

@Column (name="className") 
private String classname; 

.... setClassname (DateTime.getCanonicalName()); 

設置要檢索類;

Class.forName(classname); 

但是,如果我有你在做什麼是正確的想法,你並不需要在所有的持久化類:所有DateTimeIsBetweenCriteria實例上的日期時間操作 - 這是類的模板參數,而不是實例。你應該堅持你的日期而不是班級的行爲。

+1

謝謝您的回答。但是,您不能在數據庫中堅持Class。你可以將'clazz'列聲明爲varchar,並且hibernate支持保存Class。 – Budzu

+0

我站好了;這不是我曾遇到過的 - 謝謝!答案的最後部分是否有用? – GrumpyWelshGit

+0

但是,正如我上面提到的,我不必保存'clazz'。我需要使用'clazz'值進行一些計算。如果我不保存它(暫時),當hibernate加載標準時,'clazz'將會是空的。 – Budzu