I am using Hibernate 3.6.7 with Hibernate Search 3.4.1.
I have two entities, let's say Order, and OrderHistory. Order is in a OneToMany association with HistoryOrder:
@Entity @Table(name="Order", schema="dbo") @Indexed public class Order implements java.io.Serializable{ private Set<HistoryOrder> historyOrders = new HashSet<HistoryOrder>(0); @OneToMany(mappedBy="order") @IndexedEmbedded public Set<HistoryOrder> getHistoryOrders(){ return this.historyOrders; } } @Entity @Table(name="HistoryOrder", schema="dbo") public class HistoryOrder mplements java.io.Serializable{
private int id; private Order order;
@ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="OrderId") @ContainedIn public Order getOrder(){ return this.order; } }
Now each Order is forwarded for approval. If the approval fails (empty fields for instance) I have to record the failed attempt in the history so I save a HistoryOrder object but NOT the Order object. Since the history of the order is changed Hibernate Search tries to update the Order index too (because of the @IndexedEmbedded) but there is no open session, so throws an exception when I commit the transaction:
org.hibernate.HibernateException: Error while indexing in Hibernate Search (before transaction completion) at org.hibernate.search.backend.impl.EventSourceTransactionContext$DelegateToSynchronizationOnBeforeTx.doBeforeTransactionCompletion(EventSourceTransactionContext.java:175) at org.hibernate.engine.ActionQueue$BeforeTransactionCompletionProcessQueue.beforeTransactionCompletion(ActionQueue.java:543) at org.hibernate.engine.ActionQueue.beforeTransactionCompletion(ActionQueue.java:217) at org.hibernate.impl.SessionImpl.beforeTransactionCompletion(SessionImpl.java:571) at org.hibernate.jdbc.JDBCContext.beforeTransactionCompletion(JDBCContext.java:251) at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:138)
and
Caused by: org.hibernate.LazyInitializationException: could not initialize proxy - no Session at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:167) at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:215) at org.hibernate.search.util.HibernateHelper.unproxy(HibernateHelper.java:62) at org.hibernate.search.engine.impl.HibernateStatelessInitializer.unproxy(HibernateStatelessInitializer.java:48) at org.hibernate.search.engine.DocumentBuilderIndexedEntity.buildDocumentFields(DocumentBuilderIndexedEntity.java:459) at org.hibernate.search.engine.DocumentBuilderIndexedEntity.buildDocumentFields(DocumentBuilderIndexedEntity.java:552) at org.hibernate.search.engine.DocumentBuilderIndexedEntity.getDocument(DocumentBuilderIndexedEntity.java:443) at org.hibernate.search.engine.DocumentBuilderIndexedEntity.createAddWork(DocumentBuilderIndexedEntity.java:380) at org.hibernate.search.engine.DocumentBuilderIndexedEntity.addWorkToQueue(DocumentBuilderIndexedEntity.java:358) at org.hibernate.search.engine.WorkPlan$PerEntityWork.enqueueLuceneWork(WorkPlan.java:456) at org.hibernate.search.engine.WorkPlan$PerClassWork.enqueueLuceneWork(WorkPlan.java:257) at org.hibernate.search.engine.WorkPlan.getPlannedLuceneWork(WorkPlan.java:150) at org.hibernate.search.backend.WorkQueue.prepareWorkPlan(WorkQueue.java:134) at org.hibernate.search.backend.impl.BatchedQueueingProcessor.prepareWorks(BatchedQueueingProcessor.java:124) at org.hibernate.search.backend.impl.PostTransactionWorkQueueSynchronization.beforeCompletion(PostTransactionWorkQueueSynchronization.java:89) at org.hibernate.search.backend.impl.EventSourceTransactionContext$DelegateToSynchronizationOnBeforeTx.doBeforeTransactionCompletion(EventSourceTransactionContext.java:172)
Session context management is: <property name="current_session_context_class">thread</property>
If I save the Order object as well, I do not get exception, BUT in my case the order should not be saved. (I just had a failed attempt to forward it for approval, so I definitely should NOT save it).
One uggly workaround would be to save my Order object in a temp object then retrieve the database version of the order, call a save on that instance, save the history and send back to the screen the temp object to show to the user the values of the invalid fields.
But this is uggly, so what would be a proper way of handling this case?
|