Unable to get Updated data from View's Entity


#1

Hii,

I use the MYSQL view for Complex Queries

When I update the Original Entity with merge() method.

then the view Entity not reflect the updated Data simultaneously.


#2

Show us some code to understand what you are doing.


#3

Dear,

I am using method to save:

public Payload save(Payload payload)
	{
		MobiloitteEntityManager mobiloitteEntityManager = null;
		try
		{
			//   mobiloitteEntityManager = getEntityManager(payload.getTransferObjectMap());
			BaseEntity[] be = (BaseEntity[]) payload.getTransferObjectMap().get(SAVE_ENTITIES);
			BaseEntity[] savedBE = new BaseEntity[be.length];
			boolean keyFlag = false;
			String key = (String) payload.getTransferObjectMap().get(TRANSACTION_KEY);

			if(key == null)
			{
				key = startTransaction();
				keyFlag = true;
			}
			if(be != null)
			{
				int count = 0;
				for(BaseEntity obj:be)
				{
					IntfCacheManager intfCacheManager = DefaultCacheManagerImpl.getInstance();
					//    MobiloitteEntityManager mobiloitteEM = (MobiloitteEntityManager)intfCacheManager.pull(key);
					mobiloitteEntityManager = (MobiloitteEntityManager)intfCacheManager.pull(key);
					//     mobiloitteEM.getEntityManager().persist(obj);
					obj = mobiloitteEntityManager.getEntityManager().merge(obj);
					mobiloitteEntityManager.getEntityManager().flush();
                                        
/
					mobiloitteEntityManager.getEntityManager().refresh(obj);
					
					//TO Evict Related View of Related View 
					EvictUtil.evictMethod(obj.getClass().getName(), mobiloitteEntityManager.getEntityManager());
					savedBE[count] = obj;
					count++;
				}
			}
			if(keyFlag)
			{
				commitTransaction(key);
				payload.put(SAVE_ENTITIES,savedBE);
			}
			//   payload.getTransferObjectMap().put("dbprocess",ConstantsShared.SUCCESS);
			//   payload.setEvent(payload.getEventInternal());

			//   payload = PayloadResponse.getPayloadResponse(payload,"entityData"); //TODO set entity data to transfer object map
		}
		catch(Exception e)
		{
			e.printStackTrace();
			mobiloitteEntityManager.getEntityManager().getTransaction().rollback();
			payload.getTransferObjectMap().put("dbprocess",ConstantsShared.FAILURE);
		}
		return payload;
	}

As I found a link to Evict Method:

TO Evict Related View of Related View
EvictUtil.evictMethod(obj.getClass().getName(), mobiloitteEntityManager.getEntityManager());
With the Help of this Method

after I save the Entity and Trying to Get Data from View’s Entity
When I restart the database or Server then it reflect on getting this Entity

When I run the Genereted SQL Query form console and run in mysql workbench
then it reflect the expected Result


#4

You don’t need that:

 obj = mobiloitteEntityManager.getEntityManager().merge(obj);
mobiloitteEntityManager.getEntityManager().flush();
mobiloitteEntityManager.getEntityManager().refresh(obj);

Just use this instead:

 obj = mobiloitteEntityManager.getEntityManager().merge(obj);

More, the proper way to evict a view is to use the @Syncrhonize annotation as explained in the User Guide.


#5

I used @synchronise annotation on Related View Entity

@Entity
@Table(name="user_detail")
@NamedQueries
({
	@NamedQuery(name="UserDetail.findAll", query="SELECT u FROM UserDetail u")	
})
public class UserDetail extends BaseEntity implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	@Column(name="user_id")
	private Long userId;

	private String address;
 }
@Entity
@Table(name="user_login_detail")
@NamedQuery(name="UserLoginDetail.findAll", query="SELECT u FROM UserLoginDetail u")
public class UserLoginDetail extends BaseEntity implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	@Column(name="LOGIN_ID")
	private Long loginId;
}

//View Entity
@Entity
@Table(name="getusers")
@NamedQueries({
	//for list
	@NamedQuery(name="Getuser.findAll", query="SELECT g FROM Getuser g where g.status<>'DELETE'"),
	@NamedQuery(name="Getuser.findByRole", query="SELECT g FROM Getuser g where g.role =:role and g.status<>'DELETE' order by g.userId ASC")
})
@Synchronize( {"user_detail", "user_login_detail"} )
public class Getuser extends BaseEntity implements Serializable {
	
	private static final long serialVersionUID = 1L;

	private Long creationTime;

}

But Still Not Reflect Updated Result


#6

If the Getuser entity is already managed and stored in the Hibernate Session, you need to call refresh.

Check out the User Guide for more details about what’s the purpose of @Synchronize and why you also need refresh.


#7

Thanks for your Suggestion.
It worked after calling the refresh method on View’s Entity.

Is there any possibility to call the refresh method automatically after every save method without calling Related view’s Entity.
like for Second Level cache evict method
mobiloitteEntityManager.getEntityManager().getEntityManagerFactory().getCache().evict(Getuser.class);
OR
mobiloitteEntityManager.getEntityManager().getEntityManagerFactory().getCache().evictAll();


#8

That would not necessarily guarantee that you are using the latest data. Maybe some other Session modifies the same data as your current cached View result.

More, why do you use the View in the first place? Wouldn’t a query returning a list of DTOs work better?

Views are best when Hibernate can actually update the content of the View. Otherwise, a DTO projection is much more flexible.