0

When I try to persist an object nothing happens (Exception, error, etc) and I didn't find the cause.

My suspect is that the problem is the transactional control of Spring, because the queries work fine.

I'm using Spring 3.2 with JPA 2 and the JPA implementation is the Hibernate 4.2.18.


Entity

@Entity
@Table(name = "DOLAR")
@NamedQueries({
    @NamedQuery(name = Dolar.FIND_ALL, query = "SELECT d FROM Dolar d"),
    @NamedQuery(name = Dolar.FIND_BY_EMPRESA, query = "SELECT d FROM Dolar d WHERE d.empresa = :e")    
})

public class Dolar implements Serializable, AbstractEntity {

@Transient
private static final long serialVersionUID = 1L;
@Transient
public static final String FIND_BY_EMPRESA = "Dolar.findByEmpr";
@Transient
public static final String FIND_ALL = "Dolar.findAll";

@Id
@GeneratedValue(strategy= GenerationType.AUTO)
@Column(name="ID")
private Long id;

@OneToOne
@JoinColumn(name = "EMPRESA_ID")
private Empresa empresa;

@Column(name = "VALOR")
private BigDecimal valor;

public Dolar() {
}

Managed bean

@Controller("dolarMB")
@Scope(ViewScope.VIEW_SCOPE)
public class DolarMB extends AbstractMB<Dolar> implements Serializable {

    private static final long serialVersionUID = 7711019409135908863L;
    private static final Logger LOGGER = Logger.getLogger(DolarMB.class);

    @Autowired
    private DaoDolar dao;

    private List<Dolar> lista;
    private Dolar cadastro;
    private Empresa empresa;


    @PostConstruct
    public void init(){
    cadastro =  new Dolar();
    LOGGER.info("init:\n" + cadastro);
    }


    public void salvar() {

    if (!validate()){
       LOGGER.info("erro no cadastro");
    }else{

        cadastro = dao.salvar(cadastro);
          limparFiltro();

        }

    }
}

Dao

@Repository
public class DolarDaoImpl extends GenericDaoImpl<Dolar> implements DolarDao{

@Override
public Dolar recuperarPorEmpresa(Empresa e) {
    Query q = getConexao().createNamedQuery(Dolar.FIND_BY_EMPRESA);
    q.setParameter("empr", e);
    return (Dolar) q.getSingleResult();
}
} 


@Repository
public abstract class GenericDaoImpl<T extends AbstractEntity> implements GenericDao<T> {

@PersistenceContext
private EntityManager em;

private Class<T> clazz;
private Method m;

public GenericDaoImpl() {
   carregarClass(); 
   carregarMetodoId();
}

@Override
@Transactional
public final T salvar(T e) {
    if (e == null)
        return null;
    try {

        if (m.invoke(e) != null) {
            e = em.merge(e);
        } else {
            em.persist(e);
        }
        return e;

     } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) {
         Logger.getLogger(getClass()).error(e1);
     } catch (Exception e2) {
         Logger.getLogger(getClass()).error(e2);
     }

return null;
}

After the em.persist(e), the log show me this

08-04-2015 18:04:15 DEBUG (TransactionSynchronizationManager.java:136) - Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@46e82828] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@7113aac4] bound to thread [http-nio-8080-exec-7]
 - Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@46e82828] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@7113aac4] bound to thread [http-nio-8080-exec-7]
08-04-2015 18:04:15 TRACE (AbstractSaveEventListener.java:499) - Transient instance of: br.com.mycompany.sales.model.Dolar
 - Transient instance of: br.com.mycompany.sales.model.Dolar
08-04-2015 18:04:15 TRACE (DefaultPersistEventListener.java:202) - Saving transient instance
 - Saving transient instance
08-04-2015 18:04:15 TRACE (AbstractSaveEventListener.java:167) - Saving [br.com.mycompany.sales.model.Dolar#<null>]
 - Saving [br.com.mycompany.sales.model.Dolar#<null>]
08-04-2015 18:04:15 TRACE (ActionQueue.java:192) - Adding an EntityIdentityInsertAction for [br.com.mycompany.sales.model.Dolar] object
 - Adding an EntityIdentityInsertAction for [br.com.mycompany.sales.model.Dolar] object
08-04-2015 18:04:15 TRACE (ActionQueue.java:208) - Adding insert with no non-nullable, transient entities: [EntityIdentityInsertAction[br.com.mycompany.sales.model.Dolar#<delayed:2>]]
 - Adding insert with no non-nullable, transient entities: [EntityIdentityInsertAction[br.com.mycompany.sales.model.Dolar#<delayed:2>]]
08-04-2015 18:04:15 TRACE (ActionQueue.java:232) - Adding resolved non-early insert action.
 - Adding resolved non-early insert action.
08-04-2015 18:04:15 TRACE (UnresolvedEntityInsertActions.java:214) - No unresolved entity inserts that depended on [[br.com.mycompany.sales.model.Dolar#<delayed:2>]]
 - No unresolved entity inserts that depended on [[br.com.mycompany.sales.model.Dolar#<delayed:2>]]
08-04-2015 18:04:15 TRACE (UnresolvedEntityInsertActions.java:121) - No entity insert actions have non-nullable, transient entity dependencies.
 - No entity insert actions have non-nullable, transient entity dependencies.
08-04-2015 18:06:30 DEBUG (TransactionSynchronizationManager.java:136) - Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@46e82828] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@7113aac4] bound to thread [http-nio-8080-exec-7]
 - Retrieved value [org.springframework.orm.jpa.EntityManagerHolder@46e82828] for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@7113aac4] bound to thread [http-nio-8080-exec-7]
08-04-2015 18:06:30 TRACE (AbstractSaveEventListener.java:482) - Persistent instance of: br.com.mycompany.sales.model.Dolar
 - Persistent instance of: br.com.mycompany.sales.model.Dolar
08-04-2015 18:06:30 TRACE (DefaultPersistEventListener.java:174) - Ignoring persistent instance
 - Ignoring persistent instance
08-04-2015 18:06:30 TRACE (UnresolvedEntityInsertActions.java:121) - No entity insert actions have non-nullable, transient entity dependencies.
 - No entity insert actions have non-nullable, transient entity dependencies.

This is my configuration file

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


    <!-- Datasource  -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close">
        <property name="driverClass" value="${database.driver}" />
        <property name="user" value="${database.user}" />
        <property name="password" value="${database.password}" />
        <property name="jdbcUrl" value="${database.url}"/>
        <!-- C3P0 properties -->
        <property name="acquireIncrement" value="1" />
        <property name="maxPoolSize" value="4" />
        <property name="minPoolSize" value="1" />
        <property name="maxIdleTime" value="120" />
        <property name="initialPoolSize" value="1" />
    </bean>

    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="SALES-HOMOLOG" />
        <property name="dataSource" ref="dataSource" />
        <property name="jpaDialect" ref="jpaDialect" />
        <property name="packagesToScan">
            <list>
                <value>br.com.mycompany.sales.model</value>
            </list>
        </property>
        <property name="jpaVendorAdapter" ref="jpaVendorAdapter" />

        <property name="jpaProperties">
            <props>
                <prop key="hibernate.dialect">${database.dialect}</prop>
                <prop key="hibernate.hbm2ddl.auto">${database.hbm2ddl.auto}</prop>
                <prop key="hibernate.show_sql">${database.showSql}</prop>
                <prop key="hibernate.format_sql">${database.formatSql}</prop>
            </props>
        </property>

    </bean>

    <bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>

    <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="showSql" value="${database.showSql}" />
                <property name="generateDdl" value="true" />
                <property name="databasePlatform" value="${database.dialect}" />
    </bean>

    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

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

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





</beans>    

my persistence.xml

<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="SALES-HOMOLOG" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <class>br.com.mycompany.sales.model.Dolar</class>
    <class>br.com.mycompany.sales.model.Empresa</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
  </persistence-unit>
</persistence>
Rodolfo
  • 23
  • 1
  • 9

3 Answers3

0

The packages to scan entities shows something else than your logs shows as entity class. Your class is br.com.mycompany.sales.model.Dolar and the package that should hold the entity classes is defined like this br.com.mycompany.sales.dao. Either move the class to that package or change the package name on the class.

Daniel Jipa
  • 878
  • 11
  • 24
  • The ' packages to scan ' has been updated in question. I tell what entities are mapped through the persistence.xml file – Rodolfo Aug 05 '15 at 18:07
  • I still see the `br.com.mycompany.sales.dao` in the question. Is the same on your code? – Daniel Jipa Aug 05 '15 at 18:10
  • Now, I updated the packageToScan value for the same of Dolar class, but still has an error – Rodolfo Aug 05 '15 at 18:48
  • Maybe this is your problem http://stackoverflow.com/questions/2302802/object-references-an-unsaved-transient-instance-save-the-transient-instance-be – Daniel Jipa Aug 05 '15 at 19:01
0

first off you should show us the code that where you are trying to save the instance. try calling the method below and I think it will work.

    @Override
@Transactional
public final T salvar(T e)

this if from your GenericDaoImpl try using this.

giannisapi
  • 2,641
  • 3
  • 24
  • 31
  • Tks, @giannisapi. I forgot but now I added my controller to the question. I already use the method salvar(T e). It's called from DolarMB controller. – Rodolfo Aug 06 '15 at 12:29
  • if i see correctly your default constructor for dolar does not create anything, before this: cadastro = dao.salvar(cadastro); try assign values to the properties of your object, give it value for empresa and valor. – giannisapi Aug 06 '15 at 14:08
  • The values of object are assign by web page but I made a test putting values and nothing changed. Like this: `cadastro.setEmpresa(255L); cadastro.setId(20L); cadastro = dao.salvar(cadastro);` I changed the type of property empresa to Long too. – Rodolfo Aug 06 '15 at 15:44
  • honestly this is a very strange bug, and i am sure the bug is something that we just can not see. if you want send me the code and I will try to fix, it must be something stupid – giannisapi Aug 07 '15 at 06:57
  • try adding this em.getTransaction().commit(); and tell us if an exception occurs – giannisapi Aug 07 '15 at 06:59
  • I followed your tip and the exception is `java.lang.IllegalStateException: Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead` – Rodolfo Aug 07 '15 at 12:13
  • maybe if you try em.commit() is it available? – giannisapi Aug 07 '15 at 14:14
0

I solved the problem updating a dependency of Spring.

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-dao</artifactId>
        <version>2.0.3</version>
    </dependency>

I updated to version 2.0.8 and the transaction control worked.

Rodolfo
  • 23
  • 1
  • 9