jpacontainer entityitem never dirty or modified on concurrent access

Hi,

we are using JPAContainer with EclipseLink in JBoss Environment. And we have problems with concurrent access. We have created an CachingMutableEntityProvider like this:



package de.zad.zaddata.model.daos;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagement;

import com.vaadin.addon.jpacontainer.provider.CachingMutableLocalEntityProvider;

/**
 * 
 * @param <T>
 * 
 */
@TransactionManagement
public abstract class EjbEntityProvider<T> extends CachingMutableLocalEntityProvider<T> {

    @EJB(beanName = "GenericDao")
    protected GenericDao dao;

    protected EjbEntityProvider(Class entityClass) {
        super(entityClass);
    }

    @PostConstruct
    public void init() {
        setTransactionsHandledByProvider(false);
        setEntityManager(dao.getEntityManager());
        setEntitiesDetached(false);

    }

    @Override
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    protected void runInTransaction(Runnable operation) {
        super.runInTransaction(operation);
    }

}

persistence.xml like this:



<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" 
	xmlns="http://java.sun.com/xml/ns/persistence" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
	       http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

	<persistence-unit name="PersitenceName" transaction-type="JTA">

	<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
	<jta-data-source>java:jboss/datasources/MyDatabase</jta-data-source>
	
	<class>de.mycompany.model.entities.common.MyEntity</class>

	<shared-cache-mode>NONE</shared-cache-mode>

	<properties>
		<property name="eclipselink.target-server" value="JBoss"/>
		<property name="eclipselink.ddl-generation" value="create-tables"/>
		<property name="eclipselink.weaving" value="static"/>

	</properties>
		
	</persistence-unit>
	
</persistence>

and then we want to use it in a table and on doubleclick edit the entity in a BeanValidationForm.
so we create an entityprovider and bind it to the jpacontainer and after that a table and bind it to the jpacontainer.
That works fine.
On doubleclick event on the table we want to edit the item in the form.
Saving ( commit ) after editing in the form also works fine.
But if 2 people editing the same entity, there is no exception thrown. i think i have to use .isDirty() or .isModified() before commit on the EntityItem and set setWriteThrough(false) on the form. But the entity of the second person is not dirty if the first person has saved ( comitted ) the entity. it is ever persistent.

if you need some further imformation … let me know.
can you tell me, what should do the trick?

this works fine.

One solution to your problem is to add an
@Version
annotated field to your entity class. This is the JPA way of doing optimistic locking and getting an
OptimisticLockException
if two concurrent updates are attempted to the entity. See the code snippet below.

@Version
private Long version;

thank you, but i know this. i have forgotten to mention it. my BaseEntity ( @MappedSuperclass ) looks like this:


@Version
protected Long version;

@Column(name = "__UUID__", unique = true, nullable = false, updatable = false, length = 36)
protected String internalUUID;

and it is extended by my entity

i think miklos kiss got the same problem
here

sorry, i think this is another issue…

you are trying to synchronize to sessions which imho could be done by

  • either running a query against the db (on the version field) and check if it was modified elsewhere
  • or simple catch the optimistick lock exception
    and inform the user about the remote change, then refresh the entity.

what i am trying to solve is to know that an entity attached to a form was modified in the current session or not.

ah, ok! sorry! my problem is, that we don’t get OptimisticLockExceptions! :frowning:

np, you got 20+ more views to my topic, thank you!

but you should try out my suggested workaround:
a (native) query for the current version in the db of your entity and a check against the one in the session.

just reread your problem, you get no optimisticlock exception? thats strange.

that should be a plain jpa issue, please recheck your imports on the entity and test that the version annotation is working outside the vaadin (in a plain junit test)

isDirty and isModified should be working only within session, thats ok.

yes, you’re right!
There is no OptmisticLockException!
Version is in my BaseEntity… a mappedSuperclass!
but to be sure i will try it manually tomorrow! :slight_smile: and then i post again!

did you succeed with this?

the problem was, that i have to put version field in .setItemDataSource like this

editorForm.setItemDataSource(contactItem, Arrays.asList(
“version”
, “firstName”, “lastName”));

i did not expect this, because this should be handled by editorForm or JPA-Container.

then i get the Exception.