Disclaimer

The views and opinions expressed in this blog are my own and do not necessarily reflect those of my employer. The views and opinions expressed by visitors to this blog are theirs and do not necessarily reflect my own

Saturday, June 04, 2011

JBOSS, GWT and Request Factory : Unknown Entity Exception

I've been playing around with RequestFactory, GWT's data centric transport/serialization mechanism and was really struggling to set up a new project that could pull data from an existing set of database tables and I wanted to share my experiences if you decide to use an existing schema.

The tutorial can be found over on the GWT developer documentation and I don't want repeat what can be found there.

I decided to use an Oracle XE database and the world famous HR sample database, creating JPA entities for the EMPLOYEES and DEPARTMENTS tables.

JPA/Hibernate benefits from having a version column that is updated each time the object is persisted. RequestFactory uses this to determine whether changes have happened on the entity.

The first problem I encountered was that I kept seeing "Unknown Entity Exception" in the server logs (JBoss-6.0.0-Final). This was eventually solved by ensuring that the employees table had a "VERSION" column of type NUMBER(38). The annotated JPA class also requires the type to be of type Integer (Use the boxed/wrapper type and not int).

Initially I tried using Long for the "VERSION" column however that produces more errors in the logs and it was quickly evident this needs to be set to an Integer to be compatible with the @Version annotation.

Below is my entity definition that maps to the employees table.

@Entity
@Table(name = "EMPLOYEES", schema = "HR")
public class Employees implements Serializable {

 private static final long serialVersionUID = 1717056757381711656L;
 private static final Logger logger = Logger.getLogger(Employees.class);

 @Id
 @Column(name = "EMPLOYEE_ID")
 @NotNull
 private Long id;

 @Column(name = "VERSION")
 @Version
 private Integer version;

 @Column(name = "FIRST_NAME")
 private String firstName;

 @Column(name = "LAST_NAME")
 private String lastName;

 public Long getId() { return id; }

 public void setId(Long id) { this.id = id; }
 
 public Integer getVersion() { return version; }

 public void setVersion(Integer version) {this.version = version; }
.....
}

Finally you'll need to ensure that all rows in your schema are initialized with a default version. A simple update statement solves this:

update EMPLOYEE set version = 0;

While trying to solve this problem google searches led me down the garden path suggesting that one checks the JPA annotated class imports javax.persistence.Entity and not org.hibernate.persistence.Entity. Other searches suggested it was a incorrect configuration when using non-container based persistence. This was also not the problem as I was using a JTA datasource. The configuration for which is below.


  
    hrDS
    jdbc:oracle:thin:@localhost:1521:xe
    oracle.jdbc.driver.OracleDriver
    HR
    password
    org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter
      
         Oracle9i
      
  


My persistence.xml file was as follows:


    
        org.hibernate.ejb.HibernatePersistence
        java:hrDS
        
            
            
            
               
        
    
 

Again hope that helps someone else out there.

No comments: