Search code examples
jpaopenjpa

JPA native select followed by native update .. fires an additional update


I am trying the following which is resulting in an additional update execution and failing my tests. I have an entity like this.

@Entity
@SqlResultSetMapping(name = "tempfilenameRSMapping",
        entities = { @EntityResult(entityClass = MyEntity.class) }, 
        columns = { @ColumnResult(name = "TEMPFILENAME") })
//The reason for this mapping is to fetch an additional field data through join.
@Table(name = "MY_TABLE")
public class MyEntity {

   @Id
   @Column(name="ID")
   private String id;

   @Column(name="NAME")
   private String name;

   @Column(name="DESC")
   private String description;

   @Column(name="STATUS")
   private String status;

   //follwed by getter setters

}

I am trying to do a retrieve with a native query. And for the retrieved entity, I execute a native update (the reason for native update is that I want to update just one single field). Note that I am not updating the retrieved entity directly.

What I observe is that my update is not getting executed properly. When I turn the TRACE on, I notice that on flush openJPA is executing an additional update query and therefore overriding my original update.

e.g.

SELECT M.ID, M.NAME, M.DESC, O.TEMPFILENAME FROM MY_TABLE M, OTHER_TABLE O WHERE M.ID = ?

UPDATE MY_TABLE SET STATUS = ? WHERE ID = ?

UPDATE MY_TABLE SET ID=?, NAME=?, DESC=?, STATUS=? WHERE ID = ?

What can I do to skip the auto-updation?

Edit: Here are the routines we use for executing the queries.

The following routine returns a named native query sql.

public String getNamedNativeQuerySql(EntityManagerFactory emf, String qryName) {
    MetamodelImpl metamodel = (MetamodelImpl) emf.getMetamodel();
    QueryMetaData queryMetaData = 
    metamodel.getConfiguration().getMetaDataRepositoryInstance().getQueryMetaData(null, qryName, null, true);
    String queryString = queryMetaData.getQueryString();
    return queryString;
}

The code for retrieval:

Query query = entityManager.createNamedQuery("retrieveQry");
query.setParameter(1, id);
Object[] result = (Object[]) query.getSingleResult();
MyEntity entity = (MyEntity) result[0];
String tempFileName = (String) result[1];

The code for update that follows retrieval:

Query qry = entityManager.createNamedQuery("updateQry");
qry.setParameter(1, status);
qry.setParameter(2, entity.getId() );
qry.executeUpdate()

Edit:

I see the problem even without the update statement. OpenJPA is executing an additional update query even if I do a simple find.


Solution

  • The problem was with runtime enhancement. OpenJPA was unable to do a proper detection of dirty state with runtime-enhanced entities.

    It got resolved by doing a build time enhancement.