我正在尝试将纯JSF / Hibernate Web应用程序移植到JSF / Spring 3.0 / Hibernate / JPA应用程序。 我使用依赖注入将EntityManager的实例注入到我的DAO类中。 如果我在@PersistenceContext注释上使用type = PersistenceContextType.EXTENDED属性, 状态在浏览器之间共享,并且不显示登录页面。我试过不同的浏览器,而不仅仅是不同的窗口 就像JSF - session scoped bean shared by browsers on different machines一样 如果我没有指定EXTENDED,我无法在第一次更新后更新我的记录并获得javax.persistence.OptimisticLockException
我最近发现了一个名为View scope的东西,但我不确定这是否是解决方案。请提出一种实现这两个目标的方法 一个。在后续更新时避免使用OptimisticLockException 湾避免跨浏览器共享状态
由于 Sagar R. Kapadia
我的配置和源文件如下
DataSource.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>WEB-INF/classes/config/database/db.properties</value>
</property>
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close" >
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
</beans>
HibernateSessionFactory.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<!-- Hibernate session factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" >
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop>
<prop key="transaction.factory_class">
net.sf.hibernate.transaction.JDBCTransactionFactory
</prop>
<!--
<prop key="hibernate.transaction.factory_class">
net.sf.hibernate.transaction.JDBCTransactionFactory
</prop>
-->
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.cglib.use_reflection_optimizer">false</prop>
<prop key="hibernate.jdbc.batch_size">0</prop>
<prop key="hibernate.c3p0.min_size" >2</prop>
<prop key="hibernate.c3p0.max_size"> 5</prop>
<prop key="hibernate.c3p0.timeout">600</prop>
<prop key="hibernate.c3p0.max_statements">0</prop>
<prop key="hibernate.c3p0.idle_test_period" >300</prop>
<prop key="hibernate.c3p0.acquire_increment">1</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>com/compucloud/galleryadmin/entity/Period.hbm.xml</value>
<value>com/compucloud/galleryadmin/entity/ApplicationUser.hbm.xml</value>
<value>com/compucloud/galleryadmin/entity/Device.hbm.xml</value>
<value>com/compucloud/galleryadmin/entity/Deal.hbm.xml</value>
<value>com/compucloud/galleryadmin/entity/ComboDealItem.hbm.xml</value>
<value>com/compucloud/galleryadmin/entity/City.hbm.xml</value>
<value>com/compucloud/galleryadmin/entity/DiscountDeal.hbm.xml</value>
<value>com/compucloud/galleryadmin/entity/State.hbm.xml</value>
<value>com/compucloud/galleryadmin/entity/FreeDeal.hbm.xml</value>
<value>com/compucloud/galleryadmin/entity/OrderDetail.hbm.xml</value>
<value>com/compucloud/galleryadmin/entity/Product.hbm.xml</value>
<value>com/compucloud/galleryadmin/entity/Country.hbm.xml</value>
<value>com/compucloud/galleryadmin/entity/Category.hbm.xml</value>
<value>com/compucloud/galleryadmin/entity/Administrator.hbm.xml</value>
<value>com/compucloud/galleryadmin/entity/Company.hbm.xml</value>
<value>com/compucloud/galleryadmin/entity/ComboDeal.hbm.xml</value>
<value>com/compucloud/galleryadmin/entity/Order.hbm.xml</value>
</list>
</property>
</bean>
</beans>
faces-config.xml中
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
<application>
<el-resolver>
org.springframework.web.jsf.el.SpringBeanFacesELResolver
</el-resolver>
<variable-resolver>
org.springframework.web.jsf.DelegatingVariableResolver
</variable-resolver>
</application>
<!--Navigation rules omitted-->
</faces-config>
的web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>HelloJSF</display-name>
<!-- Add Support for Spring -->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
<!-- Change to "Production" when you are ready to deploy -->
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<!-- Welcome page -->
<welcome-file-list>
<welcome-file>faces/login.xhtml</welcome-file>
</welcome-file-list>
<!-- JSF mapping -->
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map these files with JSF -->
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<filter>
<filter-name>Extensions Filter</filter-name>
<filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Extensions Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
</web-app>
的applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<aop:aspectj-autoproxy proxy-target-class="true"/>
<context:component-scan base-package="com.compucloud.galleryadmin" />
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="MYSQL"></property>
<property name="showSql" value="true"></property>
<property name="generateDdl" value="false"></property>
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"></property>
</bean>
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" >
<property name="dataSource" ref="dataSource"></property>
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"></property>
</bean>
<!--
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor">
</bean>
<tx:annotation-driven />
-->
<tx:annotation-driven transaction-manager="demoTxManager"/>
<context:component-scan base-package="com.compucloud.galleryadmin" />
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"></bean>
<bean id="demoTxManager" class="org.springframework.orm.jpa.JpaTransactionManager" >
<property name="entityManagerFactory" ref="emf" />
</bean>
<aop:config>
<aop:pointcut id="jpaDaoMethods"
expression="execution(* com.compucloud.galleryadmin.databaseutil.Database.*.*(..))" />
<aop:advisor advice-ref="demoTxAdvice" pointcut-ref="jpaDaoMethods" />
</aop:config>
<tx:advice id="demoTxAdvice" transaction-manager="demoTxManager" >
<!--
<tx:attributes>
<tx:method name="persist*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="reset*" propagation="SUPPORTS" />
<tx:method name="load*" propagation="SUPPORTS" read-only="true" />
</tx:attributes>
-->
</tx:advice>
<!--
<tx:method name="retrieve*" propagation="SUPPORTS" read-only="true" />
<tx:method name="query*" propagation="SUPPORTS" read-only="true" />
<tx:method name="find*" propagation="SUPPORTS" read-only="false" />
-->
<!-- Database Configuration -->
<import resource="classes/config/spring/beans/DataSource.xml"/>
<import resource="classes/config/spring/beans/HibernateSessionFactory.xml"/>
<bean id="database" class="com.compucloud.galleryadmin.databaseutil.Database" scope="session" ></bean>
<bean id="country" class="com.compucloud.galleryadmin.entity.Country" scope="request"></bean>
<bean id="state" class="com.compucloud.galleryadmin.entity.State" scope="request"></bean>
<bean id="city" class="com.compucloud.galleryadmin.entity.City" scope="request"></bean>
<bean id="administrator" class="com.compucloud.galleryadmin.entity.Administrator" scope="request" ></bean>
<bean id="companyAdministrator" class="com.compucloud.galleryadmin.entity.Administrator" scope="request"></bean>
<bean id="currentAdministrator" class="com.compucloud.galleryadmin.entity.Administrator" scope="session"></bean>
<bean id="currentCompany" class="com.compucloud.galleryadmin.entity.Company" scope="session"></bean>
<bean id="company" class="com.compucloud.galleryadmin.entity.Company" scope="request" ></bean>
<bean id="category" class="com.compucloud.galleryadmin.entity.Category" scope="request"></bean>
<bean id="product" class="com.compucloud.galleryadmin.entity.Product" scope="request"></bean>
<bean id="deal" class="com.compucloud.galleryadmin.entity.Deal" scope="request" ></bean>
<bean id="discountDeal" class="com.compucloud.galleryadmin.entity.DiscountDeal" scope="request" ></bean>
<bean id="freeDeal" class="com.compucloud.galleryadmin.entity.FreeDeal" scope="request"></bean>
<bean id="comboDeal" class="com.compucloud.galleryadmin.entity.ComboDeal" scope="request"></bean>
</beans>
Database.java
@Repository
@Transactional
public class Database implements Serializable{
@PersistenceContext()
private EntityManager em;
private Exception lastException;
private Category category;
private Country country;
private State state;
private City city;
private Administrator administrator;
private Administrator companyAdministrator;
private Administrator currentAdministrator;
private Company company;
private Company currentCompany;
private Deal deal;
private DiscountDeal discountDeal;
private FreeDeal freeDeal;
private ComboDeal comboDeal;
//private Deal currentDeal;
private List<Company>listOfCompanies;
private List<Country>listOfCountries;
private List<State>listOfStates;
private List<City>listOfCities;
private List<Administrator>listOfAdministrators;
private List<Administrator>listOfCompanyAdministrators;
private List<Category> listOfCategories;
private List<Category> listOfChildCategories;
private Category currentCategory;
private Product product;
private Product productForComboDeal;
private List<Product>listOfProducts;
private List<Deal> listOfDeals;
private List<DiscountDeal> listOfDiscountDeals;
private List<FreeDeal> listOfFreeDeals;
private List<ComboDeal> listOfComboDeals;
/*
private Session m_Session;
private SessionFactory sessionFactory;
*/
/*
private UploadedFile uploadedFileCategory;
private UploadedFile uploadedFileProduct;
private UploadedFile uploadedFileProductLarge;*/
public Database(){
}
public void persistWithUpdatedFlag(Object obj){
obj=em.merge(obj);
em.flush();
refreshBeans(obj);
}
//Other Methods omitted
}
答案 0 :(得分:1)
EXTENDED表示在您明确关闭持久化上下文之前不会关闭它。由于你的Database
是一个单独的bean,所以只要你的bean(永远是),EntityManager就会存在。这就是为什么你在所有线程中看到相同的事务管理器,因为在你的EXTENDED场景中只创建了一个。
您想要的是“视图中的开放实体管理器”模式,因此您的实体管理器(持久性上下文)在请求期间保持打开,而不仅仅是事务。例如,查看OpenEntityManagerInViewFilter
。