Wednesday, December 12, 2018

JPA object is not a known entity type

I have been using EclipseLink JPA for the last 7 years successfully.  Recently, while refactoring some of code I encountered the dreaded exception message "object is not a known entity type".  In the absence of a solution for the problem I settled to use the direct approach of using connection from DataSource and executing a PreparedStatement to create a record in the database.  Not giving up on the issue stumbled across the page: https://java-error-messages.blogspot.com/2011/05/is-not-known-entity-type.html.  Based on the explanation I revisited my code, and realized my mistake, and was able to fix the error.

Base class:
@XmlRootElement
@IdClass(ExtTestCostPK.class)
@MappedSuperclass
public class ExtTestCost implements Serializable {
. . .
. . .
. . .
}

Derived Class
@XmlRootElement
@Entity
@Cacheable(false)
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
@Table(name="V_EXT_TEST_COSTS")
public class EstlTestCost extends ExtTestCost {
. . .
. . .
. . .
}

Since I was refactoring the code, I was using following code to persist:
ExtTestCost extTestCost = new ExtTestCost();
// set the class attributes

entityManager.persist(extTestCost);

This piece of code was throwing "object is not a known entity type".  Having spent one sleepless night thinking how to solve the problem, after reading the link mentioned above, realizing the mistake that ExtTestCost indeed is not an entity, modified the code to read:
@XmlRootElement
@IdClass(ExtTestCostPK.class)
@MappedSuperclass
public abstract class ExtTestCost implements Serializable {
. . .
. . .
. . .
}

ExtTestCost extTestCost = new EstlTestCost();
// set the class attributes

entityManager.persist(extTestCost);

so that ExtTestCost can not be instantiated, and ExtTestCost was instantiated as EstlTextCost which indeed is an Entity.  Eclipselink JPA created a record in the database, and the exception disappeared.  Lesson learned is declare the base class abstract so that the default no argument constructor provided by the Java compiler can not be used, and you are forced to use a derived class.