Search code examples
javaspringhibernatejpasql-view

Do Jpa& Hibernate load data which changes asynchronously in DB?


I have an oracle view in which I query my db.

create or replace view my_view as
Select cc.CCID ccid
       sm.SMCODE smcode,
       NVL(sm.smname, cc.ccname) sname
  From CC cc
 Inner Join SM sm
    On cc.id = sm.id;

I use jpa 2.1 and hibernate 4.3.7 to map my view to my entity. My entity class looks like this:

public class CCRequest implements Serializable {

    private static final long serialVersionUID = 1L;

    private String ccId;

    private String smCode;

    private String sName;
}

And my mapping xml looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
                 version="2.1">
    <entity class="CCRequest" name="CCRequest001">
        <table name="my_view"/>
        <attributes>
            <id name="ccId">
                <column name="ccid"/>
            </id>
            <basic name="smCode">
                <column name="smcode"/>
            </basic>
            <basic name="sName">
                <column name="sname"/>
            </basic>
        </attributes>
    </entity>
</entity-mappings> 

So I query my entity with jpa properly and it returns all my records. Here is the problem, when I change my data in DB asynchronously, Shockingly my jpa query returns previous records. Have I done something wrong?


Solution

  • The problem I was facing was that in spring before 4, which we had JpaTemplate for working with jpa entities, I passed EntityManager to the instances of JpaTemplate programmatically from an instance of EntityManagerFactory with no problem.

    JpaTemplate itself would do any thing for flushing EntityManager and clearing cache. When I migrate to spring 4 I faced that JpaTemplate has been dropped so I have to work with EntityManager directly.

    I get instance of EntityManager programmatically from an instance of EntityManagerFactory.

    I have a EntityManagerProvider class which create an instance of EntityManager from an instance of EntityManagerFactory.

    public class EntityManagerProvider {
    
        public static EntityManager createEntityManager(EntityManagerFactory entityManagerFactory) {
            return entityManagerFactory.createEntityManager();
        }
    }
    

    I get entityManager instance like this:

    <bean id="entityManager" class="com.tosan.novin.sipa.bo.da.jpa.EntityManagerFactoryProvider" factory-method="createEntityManager">
            <constructor-arg index="0" ref="entityManagerFactory"/>
    </bean>
    

    But I understand that if I want EntityManager to manage transactions and flushing the only way is use of @PersistenceContext for injecting EntityManager into my beans.

    @PersistenceContext
    protected EntityManager em;
    

    I am a little confused yet with this manner but my problem solved with this approach.