簡體   English   中英

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

[英]How to configure EclipseLink 2.0 and Spring 3.0.5 and Tomcat 6?

我的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.Copy spring-tomcat-weaver.jar到$ CATALINA_HOME / lib,其中$ CATALINA_HOME表示Tomcat安裝的根目錄)

第2步。 通過修改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中沒有指定path和docBase屬性

第三步。 將loadTimeWeaver屬性設置為LocalContainerEntityManagerFactoryBean

<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

我的同事在這一點上通過指出使用@Transactional的Spring事務處理而不是在實體管理器上使用事務來避免上述問題來救了我。 然后我注釋掉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);
    }
}   

當你試圖堅持時你會得到什么錯誤?

LoadTimeWeaver應該可以工作,但不是必需的。 您可以使用靜態編織。

作為@jisun回復的另一種方式。我通過注釋配置完成並刪除了更多屬性,如用戶名,密碼,驅動程序等。因為所有這些參數都可以在persistence.xml中定義:

package com.company.config;

import javax.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.core.env.Environment;
import org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver;
import org.springframework.orm.jpa.JpaTransactionManager;

@Configuration
@ComponentScan(basePackages = "com.company")
@EnableTransactionManagement
@EnableWebMvc
public class MvcConfiguration extends WebMvcConfigurerAdapter {


    @Resource
    private Environment env;

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
        emf.setPersistenceXmlLocation("classpath:persistence.xml");
        emf.setLoadTimeWeaver(new ReflectiveLoadTimeWeaver());
        return emf;
    }

    @Bean
    public JpaTransactionManager transactionManager() {
        return new JpaTransactionManager(entityManagerFactory().getObject());
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM