2011-09-19 69 views
7

我想將一個實體擴展成一個非實體,用於填充超類的字段。問題是,當我嘗試保存它時,Hibernate會拋出一個MappingException。這是因爲即使我將ReportParser投影到Report,運行時實例仍然是ReportParser,因此Hibernate抱怨它是未知的實體。如何在Hibernate中堅持一個非實體子類的實體

@Entity 
@Table(name = "TB_Reports") 
public class Report 
{ 
    Long id; 
    String name; 
    String value; 

    @Id 
    @GeneratedValue 
    @Column(name = "cReportID") 
    public Long getId() 
    { 
     return this.id; 
    } 

    public void setId(Long id) 
    { 
     this.id = id; 
    } 

    @Column(name = "cCompanyName") 
    public String getname() 
    { 
     return this.name; 
    } 

    public void setName(String name) 
    { 
     this.name = name; 
    } 

    @Column(name = "cCompanyValue") 
    public String getValue() 
    { 
     return this.name; 
    } 

    public void setValue(String value) 
    { 
     this.value = value; 
    } 
} 

ReportParser僅用於填寫字段。

public class ReportParser extends report 
{ 
    public void setName(String htmlstring) 
    { 
     ... 
    } 

    public void setValue(String htmlstring) 
    { 
     ... 
    } 
} 

嘗試將其轉換爲一個報告,並將其保存

... 
ReportParser rp = new ReportParser(); 
rp.setName(unparsed_string); 
rp.setValue(unparsed_string); 
Report r = (Report)rp; 
this.dao.saveReport(r); 

我用這個模式之前,我搬到了一個ORM,但我無法弄清楚如何與Hibernate這樣做。可能嗎?

回答

3

是否需要繼承實體?您可以使用生成器模式:

public class ReportBuilder { 
    private Report report; 
    public ReportBuilder() { 
     this.report = new Report(); 
    } 
    public ReportBuilder setName(String unparsedString) { 
     // do the parsing 
     report.setName(parsedString); 
     return this; 
    } 
    public ReportBuilder setValue(String unparsedString) { 
     // do the parsing 
     report.setValue(parsedString); 
     return this; 
    } 
    public Report build() { 
     return report; 
    } 
} 

Report report = new ReportBuilder() 
        .setName(unparsedString) 
        .setValue(unparsedString) 
        .build(); 
dao.saveReport(report); 
+0

這看起來比子類化實體更好。謝謝! – vopilif

0

你不應該擴展實體類,除非做出更專業的實體類。與實體相關的註釋保留在子類中,因此Hibernate會感到困惑。你必須知道像Hibernate這樣的JPA實現者可能(而且通常是)通過生成的代理來運行你的getters/setter。如果內部存在複雜的邏輯,您可能會遇到難以追蹤的問題。

+0

除非您告訴它,否則Hibernate不會通過任何生成的代理運行您的代碼。應該避免的不是業務邏輯,而是業務邏輯,它屬於適當結構化應用程序中的其他地方。 – Jay