2012-09-16 74 views
2

我使用Spring 3.0.6,GlassFish的3.1,EJB 3,JPA 2和我的供應商是的EclipseLink(JPA 2.0)春天Glassfish的不持續

我WEBAPPLICATION具有這些配置文件:

的persistence.xml :

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> 
<persistence-unit name="ejbPU" transaction-type="JTA"> 
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> 
<jta-data-source>tranEnterprise</jta-data-source>  
    <properties> 
    <property name="eclipselink.target-server" value="SunAS9"/> 
    <property name="eclipselink.logging.level" value="FINEST"/> 
    <property name="eclipselink.target-database" value="org.eclipse.persistence.platform.database.MySQLPlatform"/> 
</properties> 
</persistence-unit> 
</persistence> 

的applicationContext.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" 
    xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xsi:schemaLocation=" 
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-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/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 
    "> 


<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> 
    <property name="jndiName" value="tranEnterprise"/> 
</bean> 
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="persistenceUnitName" value="ejbPU"/> 
    <property name="loadTimeWeaver"> 
     <bean class="org.springframework.instrument.classloading.glassfish.GlassFishLoadTimeWeaver"/> 
    </property> 
    <property name="jpaVendorAdapter"> 
     <bean 
      class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter"> 
      <property name="showSql" value="true" /> 
     </bean> 
    </property> 
    <property name="jpaDialect"> 
     <bean 
      class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect" /> 
    </property> 
</bean> 
<tx:jta-transaction-manager /> 
<bean id="persistenceAnnotation" class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /> 
</beans> 

的web.xml

<?xml version="1.0" encoding="UTF-8"?> 
<web-app version="3.0" 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-app_3_0.xsd"> 

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>/WEB-INF/applicationContext.xml</param-value> 
</context-param> 

<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 

<servlet> 
    <servlet-name>dispatcher</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <load-on-startup>2</load-on-startup> 
</servlet> 
<servlet-mapping> 
    <servlet-name>dispatcher</servlet-name> 
    <url-pattern>*.htm</url-pattern> 
</servlet-mapping> 
<session-config> 
    <session-timeout> 
     30 
    </session-timeout> 
</session-config> 
<welcome-file-list> 
    <welcome-file>redirect.jsp</welcome-file> 
</welcome-file-list> 
</web-app> 

該項目顯示數據但不保留數據庫中的數據。我搜查了大量的一個星期,但我找不到任何答案。

我的控制器:

@EJB 
private ContractBeanLocal contractBean; 

@Transactional 
@RequestMapping(method = RequestMethod.POST) 
public String onSubmit(@ModelAttribute("contract") Contract contract) 
{ 
    try 
    { 
     contractBean.createContract(contract);     
    } catch (Exception e) 
    { 
     e.printStackTrace(); 
    } 
    return "someThing"; 
} 


@Local 
public interface ContractBeanLocal 
{ 
public void createContract(Contract contract); 
} 

@Stateful 
@Local(ContractBeanLocal.class) 
public class ContractBean implements ContractBeanLocal {  

    @PersistenceContext(unitName = "ejbPU") 
    private EntityManager em; 


    @Override 
    public void createContract(Contract contract) { 
     try { 
      em.persist(contract); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 
} 

我也試過不使用EJB,並使其由Spring

的persistence.xml管理:

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence  http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> 
    <persistence-unit name="JavaApplication2PU" transaction-type="RESOURCE_LOCAL"> 
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> 
    <class>entity.Contract</class> 
</persistence-unit> 
</persistence> 

applicationContext.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" xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
         http://www.springframework.org/schema/beans/spring-beans.xsd 
         http://www.springframework.org/schema/aop 
         http://www.springframework.org/schema/aop/spring-aop.xsd 
         http://www.springframework.org/schema/tx 
         http://www.springframework.org/schema/tx/spring-tx.xsd 
         http://www.springframework.org/schema/context 
         http://www.springframework.org/schema/context/spring-context.xsd"> 

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="persistenceUnitName" value="JavaApplication2PU"/> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="loadTimeWeaver"> 
     <bean class="org.springframework.instrument.classloading.SimpleLoadTimeWeaver"/> 
    </property> 
    <property name="jpaVendorAdapter"> 
     <bean 
      class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter"> 
      <property name="showSql" value="true" /> 
     </bean> 
    </property> 
    <property name="jpaDialect"> 
     <bean 
      class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect" /> 
    </property> 
</bean> 

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/> 
    <property name="url" value="jdbc:mysql://localhost:3306/transport2"/> 
    <property name="username" value="root"/> 
    <property name="password" value="123456"/> 
</bean> 
<bean id="ContractDaoImpl" class="dao.ContractDaoImpl"/> 

<tx:jta-transaction-manager /> 

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
    <property name="entityManagerFactory" ref="entityManagerFactory" /> 
    <property name="dataSource" ref="dataSource"/> 
</bean> 
<bean id="persistenceAnnotation" class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /> 
</beans> 

這是合同實體:

@Entity 
    @Table(name = "contract") 
    @XmlRootElement 
    public class Contract implements Serializable { 
     private static final long serialVersionUID = 1L; 
     @Id 
     @Basic(optional = false) 
     @Column(name = "contractNumber") 
     private String contractNumber; 
     @Column(name = "companyName") 
     private String companyName; 

     public Contract() { 
     } 

     public Contract(String contractNumber) { 
      this.contractNumber = contractNumber; 
     } 

     public Contract(String contractNumber, String companyName) { 
      this.contractNumber = contractNumber; 
      this.companyName = companyName; 
     } 

     public String getContractNumber() { 
      return contractNumber; 
     } 

     public void setContractNumber(String contractNumber) { 
      this.contractNumber = contractNumber; 
     } 

     public String getCompanyName() { 
      return companyName; 
     } 

     public void setCompanyName(String companyName) { 
      this.companyName = companyName; 
     } 


     @Override 
     public int hashCode() { 
      int hash = 0; 
      hash += (contractNumber != null ? contractNumber.hashCode() : 0); 
      return hash; 
     } 

     @Override 
     public boolean equals(Object object) { 
      // TODO: Warning - this method won't work in the case the id fields are not set 
      if (!(object instanceof Contract)) { 
       return false; 
      } 
      Contract other = (Contract) object; 
      if ((this.contractNumber == null && other.contractNumber != null) || (this.contractNumber != null && !this.contractNumber.equals(other.contractNumber))) { 
       return false; 
      } 
      return true; 
     } 

     @Override 
     public String toString() { 
      return contractNumber; 
     } 
    } 

package dao; 

import java.util.List; 
import entity.Contract; 

public interface ContractDao 
{ 
    void createContract(Contract contract); 

    List<Contract> getAllContract(); 

    void deleteContract(Contract contract); 
} 



package dao; 

import java.util.List; 
import javax.persistence.EntityManager; 
import javax.persistence.PersistenceContext; 
import org.springframework.transaction.annotation.Transactional; 
import entity.Contract; 


public class ContractDaoImpl implements ContractDao 
{ 
@PersistenceContext 
private EntityManager entityManager; 


    @Transactional 
    @Override 
    public void createContract(Contract contract) 
    { 
    try 
     { 
      entityManager.persist(contract); 
     } catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public List<Contract> getAllContract() 
    { 
     return entityManager.createQuery("SELECT c FROM Contract c where c.removed <> 1").getResultList(); 
    } 

    @Transactional 
    @Override 
    public void deleteContract(Contract contract) 
    { 
     entityManager.remove(contract); 
    } 
} 



package javaapplication2; 

import dao.ContractDao; 
import entity.Contract; 
import java.util.List; 
import org.springframework.context.ApplicationContext; 
import org.springframework.context.support.ClassPathXmlApplicationContext; 

public class JavaApplication2 
{ 

    public static void main(String[] args) 
    { 
     ApplicationContext applicationContext = new ClassPathXmlApplicationContext("config/applicationContext.xml"); 
    ContractDao contractDao = (ContractDao) applicationContext.getBean("ContractDaoImpl"); 

    Contract contract = new Contract(); 
    contract.setCompanyName("Freddy"); 
    contract.setContractNumber("Freddy"); 
    contractDao.createContract(contract); 
    System.out.println("Contract is successfully created"); 
    System.out.println("Contract Number is: " + contractDao.getAllContract()); 
    } 
} 

我可以獲取數據,但是當我試圖堅持,以下將引發異常:

java.lang.IllegalArgumentException: Object: contractNumber= Freddy is not a known entity type. 
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.registerNewObjectForPersist(UnitOfWorkImpl.java:4158) 
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.persist(EntityManagerImpl.java:440) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:601) 
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(Exte ndedEntityManagerCreator.java:365) 
at $Proxy8.persist(Unknown Source) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:601) 
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240) 
at $Proxy8.persist(Unknown Source) 
at dao.ContractDaoImpl.createUser(ContractDaoImpl.java:36) 
at javaapplication2.JavaApplication2.main(JavaApplication2.java:28) 
+0

嗨Canis,我有同樣的問題,你可以解決這個問題?你能分享你的解決方案嗎?謝謝!我正在使用Glassfish 4和Spring 3.我不明白爲什麼不保存..不顯示任何錯誤,但只有彈簧不能保存。 – jrey

回答

0

您需要打開一個事務(而不是隻讀)來保存某些內容:

例如:

@Controller 
@RequestMapping... 
public class MyController { 

    @Transactional //<---------- That is what you need to add. 
    @RequestMapping 
    public ModelAndView updateSomething(SomethingData somethingData, int somethingId) { 
     SomethingEntity entity = somethingDao.loadById(somethingId)); 
     entity.setX(somethingData.getX()); 
     ... 
    } 
} 

這行添加到您的Spring上下文配置

<tx:annotation-driven transaction-manager="transactionManager" /> 
+0

我已經添加了該行,但問題依然存在。 –

+0

@Canis Majoris:看到我的擴展答案,它看起來像沒有啓用交易註釋支持 – Ralph

+0

謝謝拉爾夫,我已經添加了該行,但沒有任何更改。仍然是同樣的問題 –

0
<tx:jta-transaction-manager /> 

這行看起來相當冒險。

它不應該是

<tx:annotation-driven/> 

當你說'不保存數據庫中的數據'時,它是否會拋出任何異常?

+0

我也嘗試過這一行,但沒有發生任何事情。不,它不會拋出任何異常。 –

+0

是否與你的MYSQL服務器的配置有關?我會嘗試另一個數據庫服務器,比如德比。另外我建議你直接使用數據源bean,而不是通過JNDI查找它,以便Junit測試它。 –

+0

您是直接將EntityManager注入到控制器中還是有EntityManager注入的服務bean? –

0

這聽起來像是一個類加載器的問題,很可能是由於你的Spring配置,但我不確定你的配置有什麼問題。你們是怎麼讓這個班級裝載兩個不同的班級裝載機的。

你可以在沒有Spring的情況下測試它來證實這一點。

您是否正在重新部署到實時服務器?嘗試重新啓動服務器,您可能會部署一箇舊的持久性單元。確保在取消部署時關閉EntityManagerFactory。

+0

當我不使用Spring並使用JEE框架代替時,進展順利。我的問題只是春天。順便說一句,我使用EntityManager而不是EntityManagerFactory。 –