我有三個spring + JPA項目...一個基礎項目A,一個插件項目B和實際項目C.在C中,其他兩個項目都以導入爲A.jar和B.jar。每個項目都有自己的ApplicationContext.xml。葉子項目(即C)在proeject-A的appcontext.xml中提到了自定義位置的persistence.xml(啓動項目A在整個類路徑中查找appcontext.xml和persistence.xml,因此可以從B加載xml和C)。嘗試在EntityManager關閉後加載懶惰關係
下面是我的配置, applicationContext.xml中 - 在項目中的
<bean id="jpaQueryManager" class="com.motherframework.base.dao.jpa.JPAQueryManager">
<property name="jpaTemplate" ref="jpaTemplate"/>
</bean>
<bean id="jpaTemplate" class="org.springframework.orm.jpa.JpaTemplate">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<!-- <property name="persistenceUnitManager" ref="pum"/>
<property name="persistenceUnitName" value="SchoolWebsitePersistenceUnit"/> -->
<property name="persistenceXmlLocation" value="classpath*:configuration/xml/persistence.xml"/>
<!-- <property name="persistenceUnitPostProcessors">
<list>
<bean class="com.motherframework.base.dao.jpa.EntityScanner"/>
</list>
</property> -->
<property name="dataSource"><ref bean="dataSource"/></property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="true"/>
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect"/>
</bean>
</property>
</bean>
,這是我的persistence.xml
<persistence-unit name="SchoolWebsitePersistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.motherframework.plugin.school.entity.Account</class>
<class>com.motherframework.plugin.school.entity.Module</class>
<class>com.motherframework.plugin.school.entity.NavigationMenu</class>
<class>com.motherframework.plugin.school.entity.User</class>
<properties>
<property name="dialect" value="org.hibernate.dialect.SQLServerDialect"/>
<property name="hibernate.connection.autocommit" value="true"/>
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.archive.autodetection" value="class, hbm"/>
</properties>
</persistence-unit>
現在從我的客戶端類(主要方法)我是使用@transactional Service-DAO層獲取實體(例如用戶)。
User u = ((TestService) ApplicationContext.getBean("testService")).fetchUser();
// FROM User u WHERE u.id=1 (Note: no INNER JOIN u.account)
print(u.getAccount())
應該給我NULL,但它引發異常,
DEBUG DefaultListableBeanFactory:241 - Returning cached instance of singleton bean 'org.springframework.transaction.interceptor.TransactionInterceptor#0'
DEBUG AnnotationTransactionAttributeSource:106 - Adding transactional method 'fetchUser' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly; ''
DEBUG DefaultListableBeanFactory:241 - Returning cached instance of singleton bean 'jpaTxManager'
DEBUG JpaTransactionManager:365 - Creating new transaction with name [com.motherframework.plugin.test.service.TestService.fetchUser]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly; ''
DEBUG JpaTransactionManager:323 - Opened new EntityManager [[email protected]] for JPA transaction
DEBUG JpaTransactionManager:355 - Exposing JPA transaction as JDBC transaction [SimpleConnectionHandle: jdbc:mysql://localhost:3306/schooldb, [email protected], MySQL-AB JDBC Driver]
DEBUG TransactionSynchronizationManager:183 - Bound value [[email protected]] for key [[email protected]] to thread [main]
DEBUG TransactionSynchronizationManager:183 - Bound value [[email protected]] for key [org[email protected]b8176d] to thread [main]
DEBUG TransactionSynchronizationManager:258 - Initializing transaction synchronization
DEBUG TransactionInterceptor:381 - Getting transaction for [com.motherframework.plugin.test.service.TestService.fetchUser]
DEBUG TransactionSynchronizationManager:139 - Retrieved value [[email protected]] for key [org[email protected]b8176d] bound to thread [main]
DEBUG TransactionSynchronizationManager:139 - Retrieved value [[email protected]] for key [org[email protected]b8176d] bound to thread [main]
DEBUG TransactionSynchronizationManager:139 - Retrieved value [[email protected]] for key [org[email protected]b8176d] bound to thread [main]
Hibernate: select user0_.id as id3_, user0_.accountId as accountId3_, user0_.email as email3_, user0_.loginId as loginId3_, user0_.name as name3_, user0_.password as password3_ from User user0_ where user0_.id=1
DEBUG TransactionInterceptor:410 - Completing transaction for [com.motherframework.plugin.test.service.TestService.fetchUser]
DEBUG JpaTransactionManager:925 - Triggering beforeCommit synchronization
DEBUG JpaTransactionManager:938 - Triggering beforeCompletion synchronization
DEBUG JpaTransactionManager:752 - Initiating transaction commit
DEBUG JpaTransactionManager:462 - Committing JPA transaction on EntityManager [[email protected]]
DEBUG JpaTransactionManager:951 - Triggering afterCommit synchronization
DEBUG JpaTransactionManager:967 - Triggering afterCompletion synchronization
DEBUG TransactionSynchronizationManager:311 - Clearing transaction synchronization
DEBUG TransactionSynchronizationManager:229 - Removed value [[email protected]] for key [org[email protected]b8176d] from thread [main]
DEBUG TransactionSynchronizationManager:229 - Removed value [[email protected]] for key [[email protected]] from thread [main]
DEBUG JpaTransactionManager:548 - Closing JPA EntityManager [[email protected]] after transaction
DEBUG EntityManagerFactoryUtils:329 - Closing JPA EntityManager
856 [main] ERROR org.hibernate.LazyInitializationException - could not initialize proxy - no Session
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:132)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:174)
Exception in thread "main" org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:132)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:174)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)
at com.motherframework.plugin.school.entity.Account_$$_javassist_3.toString(Account_$$_javassist_3.java)
at java.lang.String.valueOf(Unknown Source)
at java.io.PrintStream.println(Unknown Source)
at
你可以找到我的實體管理器是關閉的,所以它會給出一個異常,如果它試圖在用戶獲取帳戶....我明白...但如果entitymanager關閉,那麼爲什麼它試圖做到這一點?如何阻止它?配置有問題嗎?
還有一件事,我正在使用的entitymanagerfactory適用於生產環境(和tomcat 7)中的公共web應用程序?
在此先感謝.. :)
感謝Nizet..you意味着我PersistenceContext已經爲EntityManager的關閉關閉。但是,如果entity實際上超出了PersistenceContext,那麼爲什麼它應該嘗試獲取它的關係呢?它是一個簡單的POJO,而不是@Entity了。對於第二個問題,是的我錯過了
<tx:annotation-driven transaction-manager="jpaTxManager"/>
<bean id="jpaTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory"><ref bean="entityManagerFactory"/></property>
<property name="dataSource"><ref bean="dataSource"/></property>
</bean>
請檢查我的Entitymanager類型和transactionmanager ...是否適合生產?
這是我的DS:
<bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${motherframework.configuration.db.driver}" />
<property name="url" value="${motherframework.configuration.db.url}" />
<property name="username" value="${motherframework.configuration.db.username}" />
<property name="password" value="${motherframework.configuration.db.password}" />
但做ü要表示,雖然持久化上下文被關閉,「用戶」對象仍持有部分物業,這使得它與正常POJO不同類?
感謝Nizet ..請在我的原始問題中找到更新的DS信息...我更新了它 – 2012-08-06 12:15:47
這不是一個數據源定義。這是一個事務管理器的定義。關於你的問題:你的實體是分離的,並且你要求提供user.getAccount()。getName()?讓我們用另一個例子:'abhishek.getDisease()。isCancer()'。如果您忘記初始化該疾病,您更喜歡這種方法嗎? '假':醫生會認爲你沒有癌症,但也許你有一個。 「真的」:即使你沒有一個,醫生也會治癒你的癌症。最好的辦法是拋出一個異常,並指出存在一個錯誤:代碼從非初始化對象獲取屬性。 – 2012-08-06 12:34:18
再次感謝Nizet ..我沒有承受,你是要求實際的DS豆....請在我原來的問題中找到更新的DS信息...我更新了它 - – 2012-08-07 04:45:34