Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic callback methods(@PostLoad..) for inherited entity classes - JPA EclipseLink

My entity class hierarchy is as follows.. ClassB which extends ClassA which extends abstract mappedsuperclass AbstractClass

AbstractClass

@MappedSuperclass
public abstract class AbstractClass implements Serializable 
{

}

ClassA

@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  
    }
}

ClassB

@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  
    }
}

Problem : when i persist using ClassB entity. ClassA callback methods are not called and value in my classAXml attribute is not persisted.

Is there anyway to generalize callback method(i.e covertObjectToXml and convertXmlToObject) for my inherited entity class structure.. so that when i persist using both ClassA and ClassB individually, my callback methods are called respectively based on inheritance and their values can be persisted.

Note:

  1. I have removed the callback methods from ClassA and generalize it in classB and persist but my requirement is mainly individual persistent of classA and ClassB.
  2. my call back methods should not be in mapedSuperClass i.e AbstractClass.

Thanks in advance

like image 839
Karthigeyan Vellasamy Avatar asked Feb 02 '26 06:02

Karthigeyan Vellasamy


1 Answers

There are two possibilities to reuse the callback code from ClassA in ClassB:

I. The best/most elegant way is to move the whole code to a new class, say MyEntityListeners and then to use the @EntityListeners annotation on your entity classes like

@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`)
    }
}

Please note that the EntityListeners are inherited in the subclasses from superclasses, so you do not need to do anything in ClassB if the EntiyListeners are already defined in ClassA (but you can add additional EntityListeners in ClassB, that are not in ClassA). For excluding all EntityListeners from the hierarchy you can use @ExcludeSuperclassListeners

II. If you have less callback methods and a small hierarchy tree, than you could overwrite and re-annotate every callback from ClassA also in ClassB like

...
public class ClassB extends ClassA {
  ......
  @Override
  @PrePersist
  public void myCallback() {
        super.myCallback();
  }
  ......
}
like image 102
V G Avatar answered Feb 04 '26 21:02

V G



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!