gpt4 book ai didi

java - 如何配置 EclipseLink 2.0 和 Spring 3.0.5 以及 Tomcat 6?

转载 作者:搜寻专家 更新时间:2023-11-01 02:30:35 25 4
gpt4 key购买 nike

我的 Web 应用程序使用 Tomcat 6.0.18 和 Spring 3.0.5 以及 eclipselink 2.0.1 和 javax.persistence 2.0.0,SQL Server 数据库。我无法弄清楚配置,也无法找到具有此类配置的工作示例。我试图将 loadTimeWeaver 的属性添加到 entityManagerFacotory 中,但它破坏了 Spring 3 中的 AutoWired 注释,如下面的 applicationContext.xml 所示:

<context:load-time-weaver/>

在 appname-servlet.xml 中:

但是当我禁用 LoadTimeWeaver 时,我的应用程序可以从 JPA 代码创建数据库但无法将数据持久保存到数据库中。

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:persistence.xml" />
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="restfulPU" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="true"/>
<property name="databasePlatform" value="org.eclipse.persistence.platform.database.SQLServerPlatform"/>
</bean>
</property>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect" />
</property>
<property name="jpaPropertyMap">
<props>
<prop key="eclipselink.weaving">false</prop>
</props>
</property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
Persistence.xml
<persistence-unit name="restfulPU" transaction-type="RESOURCE_LOCAL">
<class>com.generalform.eclipselink.model.Todo</class>
<properties>
<!-- EclipseLink should create the database schema automatically -->
<property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
<property name="eclipselink.ddl-generation.output-mode"
value="database" />
</properties>

如果您能给我指点有关将 EclipseLink 集成到 Spring 3 和 Tomcat 中的指南或教程,我将不胜感激。

最佳答案

谢谢,詹姆斯。

遵循 http://static.springsource.org/spring/docs/3.0.0.M4/reference/html/ch13s05.html 处的 Springsource 指导, Tomcat 6 工作在编织上。指南中提到并复制到此处的步骤:

Step1.将spring-tomcat-weaver.jar复制到$CATALINA_HOME/lib中,其中$CATALINA_HOME代表Tomcat安装根目录)

第二步。通过修改 context.xml 告诉 Tomcat 使用自定义类加载器:

<Context path="/myWebApp" docBase="/my/webApp/location">
<Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"
useSystemClassLoaderAsParent="false"/>
</Context>

我在 $CATALINA_HOME/conf/context.xml 中没有指定路径和 docBase 属性

第三步。为 LocalContainerEntityManagerFactoryBean 开启 loadTimeWeaver 属性

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver"/>
</property>
</bean>

然后,我再次启动 Tomcat 6,启动过程变得干净。但是,数据仍然无法持久化到数据库中。错误如下:

不允许在共享 EntityManager 上创建事务 - 改用 Spring 事务或 EJB CMT

我的同事在这一点上救了我,他指出 Spring 使用 @Transactional 处理事务而不是在实体管理器上使用事务来避免上述问题。然后我注释掉了 em.getTransaction().begin() 和 em.getTransaction().commit(),只留下 em.persist(todo)。 todo 是这里的实体。它立即起作用。在这里,开发人员应该知道 JPA 事务和 Spring 事务之间的区别。其实这是EclipseLink/JPA与Spring Transaction Management配合使用时比较迷惑的地方。

我也尝试了 Tomcat 7,因为我认为它可能与 Tomcat 有关。其实这个问题与Tomcat版本无关。

启用 LoadTimeWeaver 后,它可以处理数据持久性。这是 applicationname-servlet.xml 中 transactionManager 配置部分的工作版本:

   <context:property-placeholder location="classpath:generalform.properties"/>
<context:component-scan base-package="com.generalform" />

<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${mysql.database.driver}" />
<property name="url" value="${mysql.database.url}" />
<property name="username" value="${mysql.database.user}" />
<property name="password" value="${mysql.database.password}" />
</bean>

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath:persistence.xml" />
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitName" value="restfulPU" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="true"/>
<property name="databasePlatform" value="org.eclipse.persistence.platform.database.MySQLPlatform"/>
</bean>
</property>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect" />
</property>
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver" />
</property>

</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="emf" />
</bean>

下面是我的 Dao 类,在形式上,try/catch 应该包含在方法内部的代码中:

@Repository("todoDao")
public class TodoDao {

@PersistenceContext
private EntityManager em;


public void saveTodo(Todo todo) {

System.out.println("TodoDao:saveTodo into DB >>>");
//em.getTransaction().begin();
em.persist(todo);
//em.getTransaction().commit();
em.close();
System.out.println("TodoDao: complete saveTodo into DB close()>>>");
}

}

TodoService类用@Transactional注解声明了Spring Transaction,@Autowired在启用LoadTimeWeaver后也起作用了:

@Service("todoService")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class TodoService {
@Autowired
private TodoDao todoDao;

public TodoService() {
}

@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
public void saveTodo(Todo todo) {
System.out.println("TodoService -> saveTodo is called!");
todoDao.saveTodo(todo);
}
}

关于java - 如何配置 EclipseLink 2.0 和 Spring 3.0.5 以及 Tomcat 6?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10421829/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com