Java 如何在Hibernate中持久化非实体子类中的实体

Java 如何在Hibernate中持久化非实体子类中的实体,java,hibernate,jpa,orm,annotations,Java,Hibernate,Jpa,Orm,Annotations,我试图将一个实体扩展为一个非实体,用于填充超类的字段。问题是,当我试图保存它时,Hibernate抛出一个MappingException。这是因为即使我将ReportParser转换为Report,运行时实例仍然是ReportParser,因此Hibernate抱怨它是未知实体 @Entity @Table(name = "TB_Reports") public class Report { Long id; String name; String value; @I

我试图将一个实体扩展为一个非实体,用于填充超类的字段。问题是,当我试图保存它时,Hibernate抛出一个MappingException。这是因为即使我将ReportParser转换为Report,运行时实例仍然是ReportParser,因此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来实现这一点。是否可能?

是否绝对有必要对实体进行子类化?您可以使用生成器模式:

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);

您不应该扩展实体类,除非要生成更专门的实体类。与实体相关的注释保留在子类中,因此Hibernate变得混乱


将业务逻辑放在实体类中也是很有争议的——您必须知道JPA实现者,如Hibernate,可能(通常确实)通过生成的代理运行getter/setter。由于内部逻辑复杂,您可能会遇到难以追踪的问题。

这似乎是一种比实体子类化更好的方法。谢谢Hibernate不会通过任何生成的代理运行代码,除非您告诉它。应该避免的不是业务逻辑,而是属于适当结构化应用程序中其他地方的业务逻辑。