1
votes

We are trying to build some services with entities that have common fields between them. To handle this the approach we have taken is to define a base class with all the common fields and extend all the others from this.

The base class is defined as a mapped superclass and the derived classes are regular entities. At the class level, the entities extend the base class.

To keep it modular, we have defined the base class in a common project (maven based) and in the entities in separate projects with a dependency on this common project.

The problem is that it doesn't identify/parse the mappedsuperclass. It is unable to resolve the common mappings.

So, my question is, whatever I am trying to do here, does it conform to the JPA rules/spec.

If I define the mappedsuperclass in the same mappings xml as the concrete one, it works fine. But then I have to repeat that for each project, which I want to avoid.

Here are some code snippets for the classes and mappings.

Also note here that the common mapped super class also defines a common primary key viz. ID.

The base class:

public class BaseEntity {
    String id;
    String status;    
    Date createdDate;
    String createdBy;
    Integer versionNumber;

    //getters and setters for these fields
}

Mapping xml for the base class

<entity-mappings>
    <package>mypackage</package>
    <mapped-superclass class="mypackage.BaseEntity">
        <attributes>
            <id name="id">
                <column name="ID" />
            </id>           
            <basic name="status">
                <column name="STATUS"/>
            </basic>
            <basic name="createdDate">
                <column name="CREATED_DT" />
            </basic>
            <basic name="createdBy">
                <column name="CREATED_BY" />
            </basic>
            <version name="versionNumber">
                <column name="VERSION_NUMBER" />
            </version>
        </attributes>
    </mapped-superclass>
</entity-mappings>

The persistence xml for this

<persistence>
    <persistence-unit name="test" transaction-type="RESOURCE_LOCAL">
        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
        <mapping-file>META-INF/jpa/CommonMappings.xml</mapping-file>
        <properties>
            <property name="openjpa.RuntimeUnenhancedClasses" value="supported"/> 
        </properties>
    </persistence-unit>
</persistence>

These are packaged in a separate jar.

The concrete entity

public class MyEntity extends BaseEntity {

    String name;
    String address;

    //getters and setters
}

mappings for concrete entity

<entity-mappings>
    <package>mypkg2</package>

    <entity class="mypkg2.MyEntity" name="MyEntity">                
        <table name="MYENTITY"/>

        <attributes>    
            <basic name="name">
                <column name="NAME"/>       
            </basic>

            <basic name="address">
                <column name="ADDRESS"/>        
            </basic>
        </attributes>
    </entity>

</entity-mappings>

The persistence xml for the concrete entity

<persistence>
    <persistence-unit name="test" transaction-type="RESOURCE_LOCAL">
        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
        <mapping-file>META-INF/jpa/MyEntityMappings.xml</mapping-file>
        <properties>
            <property name="openjpa.RuntimeUnenhancedClasses" value="supported"/> 
        </properties>
    </persistence-unit>
</persistence>

Edit: (based on dkaustubh's suggestion)

It works if I use annotations on my Base Entity. I have left the mappings for the derived entities in XML.

However, I want to keep the mappings consistent and would like to define it using XMLs. Why does it work with annotations but not with XML mapping?

1

1 Answers

1
votes

You can keep the base class in separate jar but you need to define it in the same persistence.xml.

Now coming to your question of not repeating the mapping for each mapping xml, you can better use annotation on your base entity. Such a way you need not repeat your mapping xml.