【问题标题】:Why are Entities not persisted in a JPA/Hibernate setup with Spring 3.2?为什么实体在 Spring 3.2 的 JPA/Hibernate 设置中没有持久化?
【发布时间】:2015-08-05 15:36:14
【问题描述】:

当我尝试持久化一个对象时,什么也没有发生(异常、错误等),我也没有找到原因。

我怀疑问题出在 Spring 的事务控制上,因为查询工作正常。

我使用 Spring 3.2 和 JPA 2,JPA 实现是 Hibernate 4.2.18。


实体

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

托管 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();

        }

    }
}

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

在 em.persist(e) 之后,日志显示这个

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.

这是我的配置文件

<?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>    

我的 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>

【问题讨论】:

  • 你的日志有错误?
  • 日志中肯定会有信息提示你问题出在哪里
  • 你如何告诉hibernate你的实体类是什么?
  • 除了可能的错误,您可以而且应该自己做更多的调试。 “什么都没有发生”是一种模糊的方式

标签: spring hibernate jpa


【解决方案1】:

扫描实体的包显示的内容不同于您的日志显示的内容 实体类。 你的类是br.com.mycompany.sales.model.Dolar,应该包含实体类的包定义如下br.com.mycompany.sales.dao。将类移动到该包或更改类上的包名称。

【讨论】:

  • “要扫描的包”已被更新。我告诉通过persistence.xml文件映射了哪些实体
  • 我仍然在问题中看到br.com.mycompany.sales.dao。你的代码也一样吗?
  • 现在,我更新了 Dolar 类的 packageToScan 值,但仍然有错误
  • 也许这是你的问题stackoverflow.com/questions/2302802/…
【解决方案2】:

首先,您应该向我们展示您尝试保存实例的代码。尝试调用下面的方法,我认为它会起作用。

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

如果从您的 GenericDaoImpl 尝试使用这个。

【讨论】:

  • 谢谢,@giannisapi。我忘记了,但现在我将控制器添加到问题中。我已经使用了方法 salvar(T e)。它是从 DolarMB 控制器调用的。
  • 如果我没看错,你的 dolar 默认构造函数不会创建任何东西,在此之前:cadastro = dao.salvar(cadastro);尝试为你的对象的属性赋值,给它赋予 empresa 和 valor 的值。
  • 对象的值是由网页分配的,但我做了一个测试,把值放在一边,没有任何改变。像这样:cadastro.setEmpresa(255L); cadastro.setId(20L); cadastro = dao.salvar(cadastro);我也把属性empresa的类型改成了Long。
  • 老实说,这是一个非常奇怪的错误,我确信这个错误是我们无法看到的。如果你想把代码发给我,我会尝试修复,这一定是愚蠢的
  • 尝试添加这个 em.getTransaction().commit();并告诉我们是否发生异常
【解决方案3】:

我解决了更新 Spring 依赖项的问题。

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

我更新到了 2.0.8 版本并且事务控制工作了。

【讨论】:

    猜你喜欢
    • 2012-11-08
    • 2011-09-22
    • 1970-01-01
    • 2021-06-26
    • 1970-01-01
    • 1970-01-01
    • 2021-05-06
    • 2018-01-05
    • 1970-01-01
    相关资源
    最近更新 更多