2015-02-12 30 views
0

使用組合的問題,我有以下實體:Tapestry 5.3.8 + Jetty + Hibernate 4.3.5 + XAMPP 1.8.3 - IdClass使用(派生)實體,它們爲什麼在嘗試合併時分離?

一些任務:

@Entity 
public class Task { 
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private long id; 
} 

一些工人:

@Entity 
public class Worker { 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    @NonVisual 
    private long id; 

} 

以及有關任務的一些情況:

@Entity 
@IdClass(TaskStatusId.class) 
public class TaskStatus { 

    @Id 
    @ManyToOne 
    private Worker worker 

    @Id 
    @ManyToOne 
    private Task task; 

} 

備註:我只有TaskStatus和其他兩個實體之間的單向關係。 Task和Worker都不包含List。

現在我有一些數據庫項目的任務和工人,和一些條目使用這些stati。這些是在應用程序啓動時創建並保留的測試對象。這一切工作正常。

現在我有一個Tapestry頁面,它可以找到一個Task和一個Worker,並將它們存儲在頁面屬性中。

SomePage.java:

@Property 
@Persist 
private Task someTask; 

@Property 
@Persist 
private Worker someWorker; 

SomePage.tml:

<t:someComponent selectedTask="someTask" selectedWorker="someWorker"/> 

在頁面A組分接收任務和工人作爲參數,並使用我的DAO層找到既使用TaskStatus ,這也有效。

SomeComponent.java:

@Parameter(required=true) 
@Property 
Task selectedTask; 

@Parameter(required=true) 
@Property 
Worker selectedWorker; 

@Property 
@Persist 
TaskStatus someStatus; 

void setupRender() { 
    if (selectedTask != null && user != null) { 
     if (someStatus == null || someStatus.getTask() != selectedTask) { 
      someStatus = taskStatusDAO.findByWorkerAndTask(selectedWorker, selectedTask); 
     } 
    } 
} 

public void onActionFromUpdateStatus() { 
    someStatus = taskStatusDAO.update(someStatus); 
} 

最後,我有一個ActionLink的在做以下組件:

  • 更新的TaskStatus對象日期字段
  • 嘗試保存使用我的DAO層更改對象,更具體地說我的合併 - 方法:

接口:

@CommitAfter 
public T update(T entity); 

實現:

public T update(T entity) { 
    return em.merge(entity); 
} 

當我嘗試合併TaskStatus對象,我得到異常:

org.hibernate.PersistentObjectException: 
detached entity passed to persist: some.package.Task 

堆棧跟蹤:

[ERROR] TapestryModule.RequestExceptionHandler Processing of request failed with uncaught exception: org.hibernate.PersistentObjectException: detached entity passed to persist: some.package.entities.Task 
org.apache.tapestry5.ioc.internal.OperationException: org.hibernate.PersistentObjectException: detached entity passed to persist: some.package.entities.Task [at classpath:some/package/components/affected/someComponent.tml, line 21] 
    at org.apache.tapestry5.ioc.internal.OperationTrackerImpl.logAndRethrow(OperationTrackerImpl.java:121) 
    at org.apache.tapestry5.ioc.internal.OperationTrackerImpl.invoke(OperationTrackerImpl.java:88) 
    at org.apache.tapestry5.ioc.internal.PerThreadOperationTracker.invoke(PerThreadOperationTracker.java:87) 
    at org.apache.tapestry5.ioc.internal.RegistryImpl.invoke(RegistryImpl.java:1124) 
    at org.apache.tapestry5.internal.structure.ComponentPageElementResourcesImpl.invoke(ComponentPageElementResourcesImpl.java:146) 
    at org.apache.tapestry5.internal.structure.ComponentPageElementImpl.triggerContextEvent(ComponentPageElementImpl.java:1058) 
    at org.apache.tapestry5.internal.services.AjaxComponentEventRequestHandler.handle(AjaxComponentEventRequestHandler.java:110) 
    at org.apache.tapestry5.internal.services.ajax.AjaxFormUpdateFilter.handle(AjaxFormUpdateFilter.java:56) 
    at $ComponentEventRequestHandler_20d7f9a2019d1.handle(Unknown Source) 
    at $ComponentEventRequestHandler_20d7f9a2019c9.handle(Unknown Source) 
    at org.apache.tapestry5.internal.services.AjaxFilter.handle(AjaxFilter.java:42) 
    at $ComponentEventRequestHandler_20d7f9a2019cb.handle(Unknown Source) 
    at org.apache.tapestry5.upload.internal.services.UploadExceptionFilter.handle(UploadExceptionFilter.java:75) 
    at $ComponentEventRequestHandler_20d7f9a2019cb.handle(Unknown Source) 
    at org.apache.tapestry5.services.TapestryModule$41.handle(TapestryModule.java:2475) 
    at $ComponentEventRequestHandler_20d7f9a2019cb.handle(Unknown Source) 
    at $ComponentEventRequestHandler_20d7f9a2018ce.handle(Unknown Source) 
    at org.apache.tapestry5.internal.services.ComponentRequestHandlerTerminator.handleComponentEvent(ComponentRequestHandlerTerminator.java:43) 
    at some.package.services.PageProtectionFilter.handleComponentEvent(PageProtectionFilter.java:94) 
    at $ComponentRequestFilter_20d7f9a2018cd.handleComponentEvent(Unknown Source) 
    at $ComponentRequestHandler_20d7f9a2018d0.handleComponentEvent(Unknown Source) 
    at org.apache.tapestry5.services.InitializeActivePageName.handleComponentEvent(InitializeActivePageName.java:39) 
    at $ComponentRequestHandler_20d7f9a2018d0.handleComponentEvent(Unknown Source) 
    at $ComponentRequestHandler_20d7f9a20189c.handleComponentEvent(Unknown Source) 
    at org.apache.tapestry5.internal.services.ComponentEventDispatcher.dispatch(ComponentEventDispatcher.java:46) 
    at $Dispatcher_20d7f9a20189f.dispatch(Unknown Source) 
    at $Dispatcher_20d7f9a201898.dispatch(Unknown Source) 
    at org.apache.tapestry5.services.TapestryModule$RequestHandlerTerminator.service(TapestryModule.java:302) 
    at some.package.services.AppModule$1.service(AppModule.java:175) 
    at $RequestFilter_20d7f9a201897.service(Unknown Source) 
    at $RequestHandler_20d7f9a201899.service(Unknown Source) 
    at org.apache.tapestry5.internal.services.RequestErrorFilter.service(RequestErrorFilter.java:26) 
    at $RequestHandler_20d7f9a201899.service(Unknown Source) 
    at org.apache.tapestry5.services.TapestryModule$3.service(TapestryModule.java:902) 
    at $RequestHandler_20d7f9a201899.service(Unknown Source) 
    at org.apache.tapestry5.services.TapestryModule$2.service(TapestryModule.java:892) 
    at $RequestHandler_20d7f9a201899.service(Unknown Source) 
    at org.apache.tapestry5.internal.services.StaticFilesFilter.service(StaticFilesFilter.java:90) 
    at $RequestHandler_20d7f9a201899.service(Unknown Source) 
    at org.apache.tapestry5.internal.services.CheckForUpdatesFilter$2.invoke(CheckForUpdatesFilter.java:105) 
    at org.apache.tapestry5.internal.services.CheckForUpdatesFilter$2.invoke(CheckForUpdatesFilter.java:96) 
    at org.apache.tapestry5.ioc.internal.util.ConcurrentBarrier.withRead(ConcurrentBarrier.java:85) 
    at org.apache.tapestry5.internal.services.CheckForUpdatesFilter.service(CheckForUpdatesFilter.java:119) 
    at $RequestHandler_20d7f9a201899.service(Unknown Source) 
    at $RequestHandler_20d7f9a20188d.service(Unknown Source) 
    at org.apache.tapestry5.services.TapestryModule$HttpServletRequestHandlerTerminator.service(TapestryModule.java:253) 
    at org.got5.tapestry5.jquery.services.AjaxUploadServletRequestFilter.service(AjaxUploadServletRequestFilter.java:27) 
    at $HttpServletRequestHandler_20d7f9a20188f.service(Unknown Source) 
    at org.apache.tapestry5.internal.gzip.GZipFilter.service(GZipFilter.java:53) 
    at $HttpServletRequestHandler_20d7f9a20188f.service(Unknown Source) 
    at org.apache.tapestry5.upload.internal.services.MultipartServletRequestFilter.service(MultipartServletRequestFilter.java:44) 
    at $HttpServletRequestHandler_20d7f9a20188f.service(Unknown Source) 
    at org.apache.tapestry5.internal.services.IgnoredPathsFilter.service(IgnoredPathsFilter.java:62) 
    at $HttpServletRequestFilter_20d7f9a20188a.service(Unknown Source) 
    at $HttpServletRequestHandler_20d7f9a20188f.service(Unknown Source) 
    at org.apache.tapestry5.services.TapestryModule$1.service(TapestryModule.java:852) 
    at $HttpServletRequestHandler_20d7f9a20188f.service(Unknown Source) 
    at $HttpServletRequestHandler_20d7f9a201888.service(Unknown Source) 
    at org.apache.tapestry5.TapestryFilter.doFilter(TapestryFilter.java:171) 
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1148) 
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:387) 
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) 
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181) 
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765) 
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:417) 
    at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230) 
    at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114) 
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) 
    at org.mortbay.jetty.Server.handle(Server.java:324) 
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:535) 
    at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:880) 
    at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:747) 
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218) 
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404) 
    at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409) 
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:520) 
Caused by: org.apache.tapestry5.runtime.ComponentEventException: org.hibernate.PersistentObjectException: detached entity passed to persist: some.package.entities.Task [at classpath:some/package/components/affected/someComponent.tml, line 21] 
    at org.apache.tapestry5.internal.structure.ComponentPageElementImpl.processEventTriggering(ComponentPageElementImpl.java:1141) 
    at org.apache.tapestry5.internal.structure.ComponentPageElementImpl.access$3100(ComponentPageElementImpl.java:61) 
    at org.apache.tapestry5.internal.structure.ComponentPageElementImpl$5.invoke(ComponentPageElementImpl.java:1062) 
    at org.apache.tapestry5.internal.structure.ComponentPageElementImpl$5.invoke(ComponentPageElementImpl.java:1060) 
    at org.apache.tapestry5.ioc.internal.OperationTrackerImpl.invoke(OperationTrackerImpl.java:74) 
    ... 74 more 
Caused by: javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: some.package.entities.Task 
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1763) 
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677) 
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1683) 
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:1206) 
    at $EntityManager_14b7d075216.merge($EntityManager_14b7d075216.java) 
    at some.package.dao.AbstractDAOImpl.update(AbstractDAOImpl.java:34) 
    at $TaskStatusDAO_20d7f9a2019e4.update(Unknown Source) 
    at $TaskStatusDAO_20d7f9a2019e5.advised$update_20d7f9a2019eb(Unknown Source) 
    at $TaskStatusDAO_20d7f9a2019e5$Invocation_update_20d7f9a2019ea.proceedToAdvisedMethod(Unknown Source) 
    at org.apache.tapestry5.internal.plastic.AbstractMethodInvocation.proceed(AbstractMethodInvocation.java:84) 
    at org.apache.tapestry5.internal.jpa.CommitAfterMethodAdvice.advise(CommitAfterMethodAdvice.java:48) 
    at org.apache.tapestry5.internal.plastic.AbstractMethodInvocation.proceed(AbstractMethodInvocation.java:86) 
    at $TaskStatusDAO_20d7f9a2019e5.update(Unknown Source) 
    at $TaskStatusDAO_20d7f9a201879.update(Unknown Source) 
    at some.package.components.affected.someComponent.onActionFromSendConfirmation(someComponent.java:59) 
    at some.package.components.affected.someComponent.dispatchComponentEvent(someComponent.java) 
    at org.apache.tapestry5.internal.structure.ComponentPageElementImpl.dispatchEvent(ComponentPageElementImpl.java:932) 
    at org.apache.tapestry5.internal.structure.ComponentPageElementImpl.processEventTriggering(ComponentPageElementImpl.java:1117) 
    ... 78 more 
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: some.package.entities.Task 
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:139) 
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75) 
    at org.hibernate.tuple.entity.AbstractEntityTuplizer$IncrediblySillyJpaMapsIdMappedIdentifierValueMarshaller.getIdentifier(AbstractEntityTuplizer.java:494) 
    at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:342) 
    at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:4746) 
    at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:129) 
    at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:76) 
    at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:876) 
    at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:858) 
    at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:863) 
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:1196) 
    ... 92 more 

如果我創建一個分離te標識符,並且不使用複合標識,更新/合併TaskStatus工作。但是,如果我不需要,我寧願不改變它。

如何使用派生(?)實體使用複合ID?

回答

0

如果爲每個HTTP請求創建了一個新的Hibernate會話(這很可能發生),那麼您面臨的問題是由於您在會話中系統地保存數據庫中的數據(屬性爲「someTask ','someWorker'和'someStatus')。

什麼hapening:

  • 第一次HTTP請求:渲染頁面

    • 創建一個新的Hibernate Session。
    • 在此HTTP請求結束時,您的屬性值存儲在會話中,同時您的Hibernate會話關閉。
  • 第二HTTP請求:從更新狀態

    • 創建一個新的Hibernate Session行動。
    • Tapestry從用戶會話中獲取屬性的值,並將它們重新存入組件的java屬性中。但是這些值不會連接到新的Hibernate會話,這會導致在使用其中一個DAO調用DAO時出現的錯誤。

爲了解決這個問題,我想你應該:

  • 避免使用持久性(?我覺得你並不需要那麼這裏做),
  • 調用「讀取「你的DAO的方法在每個HTTP請求開始時獲得一個連接到休眠會話的新鮮Hibernate實體,然後在這個實體上做你的東西。
相關問題