[Hibernate-JIRA] Created: (EJB-331) StaleObjectStateException after removing two entities
by ludki (JIRA)
StaleObjectStateException after removing two entities
-----------------------------------------------------
Key: EJB-331
URL: http://opensource.atlassian.com/projects/hibernate/browse/EJB-331
Project: Hibernate Entity Manager
Issue Type: Bug
Components: EntityManager
Affects Versions: 3.3.1.GA
Environment: Hibernate EntityManager 3.3.1.GA
Hibernate Annotations 3.3.0.GA
Hibernate Core 3.2.5
Oracle 9.2.0.7.0
Oracle JDBC driver 10.1.0.4.0
Reporter: ludki
Attachments: test.zip
The szenrio is very simple : we have two entities EntityA, EntityB with a relation (EntityA.eB <-> EntityB.eA) between them.
The foreign key 'eB_id' is located at the table of EntityA.
The Lock-Strategy of both Entities is
@org.hibernate.annotations.Entity(optimisticLock = org.hibernate.annotations.OptimisticLockType.DIRTY, dynamicUpdate = true)
The initial state can be reached as follows:
@PersistenceContext
EntityManager m;
public void create() {
EntityA a = new EntityA(1); // PrimaryKey = 1
EntityB b = new EntityB(1); // PrimaryKey = 1
a.eB = b;
b.eA = a;
m.persist(a);
m.persist(b);
}
in a new Transaction (or after a flush) we have first to release the relation between the two Entities and then remove them. For getting the Exception it is important to remove the Entity which contains the foreign key at last:
private void remove() {
EntityA a = m.find(EntityA.class, 1);
EntityB b = m.find(EntityB.class, 1);
m.remove(b);
m.remove(a);
}
A flush before the removes or switching the two removes will prevent the Exception.
The generated (and obviously erroneous) SQL-Statements for the remove-method are listed below:
update EntityA set eB_id=null where key=1 and eB_id=1
delete from EntityB where key=1
delete from EntityA where key=1 and eB_id = 1 <-- eB_id was set to null two lines ago, therefore the delete causes an EntityNotFoundException
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [test.EntityA#1]
at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1765)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2523)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2697)
at org.hibernate.action.EntityDeleteAction.execute(EntityDeleteAction.java:74)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:234)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:146)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.ejb.AbstractEntityManagerImpl$1.beforeCompletion(AbstractEntityManagerImpl.java:516)
at com.arjuna.ats.internal.jta.resources.arjunacore.SynchronizationImple.beforeCompletion(SynchronizationImple.java:114)
at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.beforeCompletion(TwoPhaseCoordinator.java:247)
at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.end(TwoPhaseCoordinator.java:86)
at com.arjuna.ats.arjuna.AtomicAction.commit(AtomicAction.java:177)
at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1389)
at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.commit(BaseTransaction.java:135)
at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.commit(BaseTransactionManagerDelegate.java:87)
at org.jboss.aspects.tx.TxPolicy.endTransaction(TxPolicy.java:175)
at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:87)
at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:191)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:95)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:110)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.stateless.StatelessContainer.dynamicInvoke(StatelessContainer.java:304)
at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:106)
at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:82)
at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:769)
at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:573)
at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:373)
at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:166)
javax.persistence.EntityNotFoundException: Unable to find test.EntityA with id 1
at org.hibernate.ejb.Ejb3Configuration$Ejb3EntityNotFoundDelegate.handleEntityNotFound(Ejb3Configuration.java:109)
at org.hibernate.impl.SessionImpl.load(SessionImpl.java:797)
at org.hibernate.ejb.AbstractEntityManagerImpl.wrapStaleStateException(AbstractEntityManagerImpl.java:640)
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:600)
at org.hibernate.ejb.AbstractEntityManagerImpl$1.beforeCompletion(AbstractEntityManagerImpl.java:525)
at com.arjuna.ats.internal.jta.resources.arjunacore.SynchronizationImple.beforeCompletion(SynchronizationImple.java:114)
at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.beforeCompletion(TwoPhaseCoordinator.java:247)
at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.end(TwoPhaseCoordinator.java:86)
at com.arjuna.ats.arjuna.AtomicAction.commit(AtomicAction.java:177)
at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1389)
at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.commit(BaseTransaction.java:135)
at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.commit(BaseTransactionManagerDelegate.java:87)
at org.jboss.aspects.tx.TxPolicy.endTransaction(TxPolicy.java:175)
at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:87)
at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:191)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:95)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:110)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.stateless.StatelessContainer.dynamicInvoke(StatelessContainer.java:304)
at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:106)
at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:82)
at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:769)
at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:573)
at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:373)
at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:166)
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
16 years, 2 months
[Hibernate-JIRA] Created: (HSEARCH-185) Add selective property embedding in @IndexedEmbedded
by Stephane Epardaud (JIRA)
Add selective property embedding in @IndexedEmbedded
----------------------------------------------------
Key: HSEARCH-185
URL: http://opensource.atlassian.com/projects/hibernate/browse/HSEARCH-185
Project: Hibernate Search
Issue Type: New Feature
Components: mapping
Affects Versions: 3.0.1.GA
Reporter: Stephane Epardaud
Priority: Minor
We use @IndexedEmbedded for two reasons:
- Filtering entities based on some embedded entity fields in a HS filter
- Searching through the "text" field of every entity embedded in a root entity
If we could specify the fields that we embed we would not need to embed a whole entity in the index. For instance we don't need to embed its ID in most cases, or fields which might be useful for one embedding and not another one.
If we could add the following to the @IndexedEmbedded annotation:
String[] fields() default {};
We could achieve the desired goal. An empty value would mean "embed all the fields" (this is still subject to depth), while a non-empty value would mean "only embed those fields" (still subject to depth).
This would be ideal in our current case if combined with @IndexedEmbeddeds: in our example, we have an Order entity which has several "actors" such as _buyer_ and _seller_. We need to embed the keys of those actors in the Order index in order to use them from our HS filter. We also have several "text" fields in Order and there are some in Person which we'd like to embed:
{code}
@Indexed
@Entity
public void Order implements Serializable {
...
@IndexedEmbeddeds({
// this is used by the filter for security
@IndexedEmbedded(prefix="contacts.", fields={"key"}, depth=1),
// this is for full-text search
@IndexedEmbedded(prefix="", fields={"text"}, depth=1)
})
private Person buyer;
@IndexedEmbeddeds({
// this is used by the filter for security
@IndexedEmbedded(prefix="contacts.", fields={"key"}, depth=1),
// this is for full-text search
@IndexedEmbedded(prefix="", fields={"text"}, depth=1)
})
private Person seller;
@Field(name = "text", index = Index.TOKENIZED)
private String description;
...
}
@Indexed
@Entity
public class Person implements Serializable {
...
@Fields({
// this is for full-text search
@Field(name = "text"),
// this is for security checks in the filters
@Field(name = "key", index = Index.UN_TOKENIZED, store = Store.YES)
)}
private String key;
@Field(name = "text", index = Index.TOKENIZED)
private String name;
}
{code}
What do you think?
This is a real-world requirement, and I don't think it should be too difficult to implement so if you agree with its usefulness I'm ready to back it up with a patch.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
16 years, 2 months