【问题标题】:How to persist an entity from an non-entity subclass in Hibernate如何在 Hibernate 中从非实体子类中持久化实体
【发布时间】:2011-11-20 00:41:38
【问题描述】:

我正在尝试将实体扩展为用于填充超类字段的非实体。问题是当我尝试保存它时,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 来做到这一点。有可能吗?

【问题讨论】:

    标签: java hibernate jpa orm annotations


    【解决方案1】:

    对实体进行子类化是绝对必要的吗?您可以使用构建器模式:

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

    【讨论】:

    • 这似乎比继承实体更好。谢谢!
    【解决方案2】:

    您不应该扩展实体类,除非制作更专业的实体类。实体相关的注解保留在子类中,因此 Hibernate 会混淆。

    将业务逻辑放在实体类中也值得商榷——您必须知道,JPA 实现者,如 Hibernate,可能(并且通常会)通过生成的代理运行您的 getter/setter。内部逻辑复杂,你可能会遇到难以追踪的问题。

    【讨论】:

    • Hibernate 不会通过任何生成的代理运行您的代码,除非您告诉它这样做。应该避免的不是业务逻辑,而是属于结构合理的应用程序中其他地方的业务逻辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-20
    相关资源
    最近更新 更多