2

I use Spring 3.0.6, GlassFish 3.1, EJB 3, JPA 2 and my provider is EclipseLink (JPA 2.0)

My webApplication has these configuration files:

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>

This project shows data but doesn't persist data in database. I searched a lot for a week but I couldn't find any answer.

My controller:

@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();
        }
    }
}

I also tried to not use EJB and made it managed by 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>

This is the Contract Entity:

    @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());
    }
}

I can fetch the data but when I try to persist, the following exception will be thrown:

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)
Canis Majoris
  • 1,016
  • 1
  • 7
  • 18
  • Hi Canis, I have the same problem, you can solve this issue? could you share your solution? thanks! I am working with Glassfish 4 and Spring 3. I cannot understand why does not save.. does not show anything error but with spring only does not save. – jrey Jul 28 '14 at 15:28

3 Answers3

0

You need to open an transaction (not readonly) to save something:

For example:

@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());
       ...
    }
}

and add this line to your spring context configuration

<tx:annotation-driven transaction-manager="transactionManager" />
Ralph
  • 118,862
  • 56
  • 287
  • 383
0
<tx:jta-transaction-manager />

This line looks pretty dodgy to me.

Shouldn't it be

<tx:annotation-driven/>

?

When you say 'doesn't persist data in database', does it throw any exception?

Mingtao Sun
  • 1,078
  • 3
  • 9
  • 14
0

This sounds like a class loader issue, most likely due to your Spring configuration, but I'm not sure what is wrong in your config. You some how have the class loaded by two different class loaders.

You could test it without Spring to confirm this.

Are you redploying to a live server? Try restarting the server, you might have an old persistence unit deployed. Ensure you close your EntityManagerFactory when undeploying.

James
  • 17,965
  • 11
  • 91
  • 146
  • When I don't use Spring and use JEE framework instead, everything goes well. My problem is just Spring. By the way I use EntityManager instead of EntityManagerFactory. – Canis Majoris Sep 19 '12 at 05:36