【问题标题】:Generic callback methods(@PostLoad..) for inherited entity classes - JPA EclipseLink继承实体类的通用回调方法(@PostLoad..) - JPA EclipseLink
【发布时间】:2013-10-22 21:14:45
【问题描述】:

我的实体类层次结构如下.. ClassB 扩展 ClassA 扩展抽象映射超类 AbstractClass

抽象类

@MappedSuperclass
public abstract class AbstractClass implements Serializable 
{

}

A 类

@Table(name = "TABLE_ONE")
@SecondaryTable(name = "TABLE_TWO", 
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="Type", discriminatorType=DiscriminatorType.STRING)
@DiscriminatorValue("ClassA")
public class ClassA extends AbstractClass
{
    @Column(name = "CLASSA_XML")
    private String ClassAXML;

    @PrePersist
    @PreUpdate
    public void covertObjectToXml()
    {
        this.ClassAXML= JAXBUtilities.marshal(Object);
    }

    @PostLoad
    public void convertXmlToObject()
    {
       //does unmarshal  
    }
}

B 类

@DiscriminatorValue("ClassB")
public class ClassB extends ClassA 
{
    @Column(name = "CLASSB_XML", table = "TABLE_TWO")
    private String ClassBXML;

    @PrePersist
    @PreUpdate
    public void covertObjectToXml()
    {
        this.ClassAXML= JAXBUtilities.marshal(Object);
    }

    @PostLoad
    public void convertXmlToObject()
    {
       //does unmarshal  
    }
}

问题:当我坚持使用 ClassB 实体时。未调用 ClassA 回调方法,并且我的 classAXml 属性中的值未保留。

是否有为我继承的实体类结构概括回调方法(即covertObjectToXml和convertXmlToObject)..以便当我坚持使用 ClassA 和 ClassB 都是单独的,我的回调方法是基于继承分别调用的,并且它们的值可以被持久化。

注意:

  1. 我已从 ClassA 中删除了回调方法并将其概括为 classB 并坚持,但我的要求主要是个人的 classA 和 ClassB 的持久化。
  2. 我的回调方法不应该在 mapedSuperClass 中,即 AbstractClass。

提前致谢

【问题讨论】:

    标签: java inheritance jpa entity eclipselink


    【解决方案1】:

    ClassB 中重用来自ClassA 的回调代码有两种可能性:

    I. 最好/最优雅的方法是将整个代码移到一个新类中,比如MyEntityListeners 然后在您的实体类上使用@EntityListeners 注释,例如

    @EntityListeners(class=MyEntityListeners.class)
    public class ClassB extends ClassA {
      .....
    }
    
    public class MyEntityListeners {
        @PrePersist
        public void onPrePersist(Object entity) {
            //logic with entity (check the class of the entity or you can use `ClassA` instead of `Object`)
        }
    }
    

    请注意,EntityListeners 是超类的子类中的inherited,因此如果 EntiyListeners 已在 ClassA 中定义,则无需在 ClassB 中执行任何操作(但您可以在B 类,不在 A 类中)。要从层次结构中排除 所有 EntityListener,您可以使用@ExcludeSuperclassListeners

    II.如果您的回调方法较少且层次结构树较小,那么您可以覆盖并重新注释来自ClassA 的每个回调,也可以在ClassB 中类似

    ...
    public class ClassB extends ClassA {
      ......
      @Override
      @PrePersist
      public void myCallback() {
            super.myCallback();
      }
      ......
    }
    

    【讨论】:

    • 使用 super 对 ClassA 和 ClassB 的个人持久性都有效。但我有一个疑问,概括使用 EntityListener 对我有好处,因为我可能会在“n”个实体类中使用它,因为这两种方法对所有人都是通用的。现在我的问题是我必须将一个类实例传递给这个回调方法(即 MyEntityListeners)以在它们各自的实体上设置列值。你可以为这个问题提出任何建议吗?
    • 这不是问题:您在MyEntityListeners 的回调方法中获得了您的实体实例。 EntityListeners 也是继承的。请参阅我的更改回复。
    猜你喜欢
    • 1970-01-01
    • 2015-05-29
    • 2018-09-15
    • 2013-12-04
    • 1970-01-01
    • 1970-01-01
    • 2015-08-02
    • 2011-12-30
    • 1970-01-01
    相关资源
    最近更新 更多