【问题标题】:Hibernate, properties changes not tracked休眠,不跟踪属性更改
【发布时间】:2014-10-11 02:13:55
【问题描述】:

我正在用 spring webflow 2.4 和 hibernate 4.3 编写一个 web 应用程序。 调用persist() 后对实体所做的更改有问题。不会跟踪这些更改,甚至在流程结束之前调用 saveOrUpdate 也无济于事(无论如何应该没用)。

Hib 配置

<bean id="oracleDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
        <property name="url" value="${db.oracle.url}" />
        <property name="username" value="${db.oracle.user}" />
        <property name="password" value="${db.oracle.password}" />
    </bean>

<bean id="oracleSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="oracleDataSource" />
    <property name="entityInterceptor">
        <bean class="be.core.dao.interceptor.AuditInterceptor"/>
    </property>
    <property name="hibernateProperties">
        <value>
            hibernate.temp.use_jdbc_metadata_defaults=false
            hibernate.default_schema=
            hibernate.dialect=org.hibernate.dialect.Oracle9Dialect
        </value>
    </property>
    <property name="packagesToScan">
        <value>domain</value>
    </property>
</bean>

实体:

@Entity
@Table(name = "ACT")
@SequenceGenerator(name = "ACT_SEQ", sequenceName = "ACT_SEQ")
public class Act extends BaseEntity<Long> {

    private static final long serialVersionUID = -731258565201165908L;

    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator = "ACT_SEQ")
    @Column(name="ACTNUM")
    private Long id;

    @NotFound(action=NotFoundAction.IGNORE)
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="SOCNUM")
    private Enterprise enterprise;

    @DateFormat(pattern = "dd/MM/yyyy")
    @Temporal(TemporalType.DATE)
    @Column(name="ACTEDATE")
    private Date date;

    @Column(name = "ACTE", nullable = false, length = 12)
    private String actRef;

流控制器中的代码:

public Act createBaseAct(Enterprise enterprise, User user) {
        Act act = new Act(enterprise);
        act.setWho(user.getWho());
        act.setSource(SOURCE);
        actDao.persist(act);
        return act;
    }

调用persist()时,使用声明的序列正确生成id。

在流程结束时,提交被执行但导致错误,因为属性actRef是在persist()之后设置的并且没有被跟踪:

    DEBUG: org.hibernate.SQL - insert into ACT (DATCRE, MAJD, version, QUI, ACTE, ACTEDATE, SOCNUM, ACTENOPG, ACTELNG, ACTEDRPG, ACTESRC, ACTENUM) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
TRACE: org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl - Registering statement [oracle.jdbc.driver.OraclePreparedStatement@181496]TRACE: org.hibernate.persister.entity.AbstractEntityPersister - Dehydrating entity: [domain.Act#236871950]
    TRACE: org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [1] as [DATE] - [Mon Aug 18 09:35:11 CEST 2014]
    TRACE: org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [2] as [DATE] - [Mon Aug 18 09:35:11 CEST 2014]
    TRACE: org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [3] as [INTEGER] - [0]
    TRACE: org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [4] as [VARCHAR] - [QP]
    TRACE: org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [5] as [VARCHAR] - [null]
    TRACE: org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [6] as [DATE] - [Mon Aug 18 09:35:11 CEST 2014]
    TRACE: org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [7] as [BIGINT] - [404371]
    TRACE: org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [8] as [INTEGER] - [1]
    TRACE: org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [9] as [VARCHAR] - [null]
    TRACE: org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [10] as [INTEGER] - [1]
    TRACE: org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [11] as [VARCHAR] - [6010]
    TRACE: org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [12] as [BIGINT] - [236871950]
    DEBUG: org.hibernate.engine.jdbc.spi.SqlExceptionHelper - could not execute statement [n/a]
    java.sql.SQLException: ORA-01400: cannot insert NULL into ("ACT"."ACTE")

在流程执行中进一步设置了一些属性,但即使我在persist() 之后直接设置属性,它也不会被跟踪...

我看不出我在这里做错了什么,应该管理实体。有人对此有提示吗?

谢谢。

【问题讨论】:

    标签: spring hibernate spring-webflow


    【解决方案1】:

    当调用persist()时,id是使用正确生成的 声明的序列。

    这是不可能的,因为您在 ACTE 字段上有 not_null 约束。

    查看 STrace 中的最后一行。 错误正确地指出cannot insert NULL into ("ACT"."ACTE")

    您必须在 persist() 对象之前设置 actRef 中的值。

    【讨论】:

    • id生成了,是可以的。仅在提交时检查约束
    【解决方案2】:

    是的,我知道这是因为非空约束,这很清楚。我认为hibernate会先插入,然后更新持久化后所做的更改……这就是为什么它是SQL异常的原因。我希望 hibernate 在创建插入语句之前解决对实体所做的更改。显然,除了在流程的最后坚持,没有办法强制执行。
    问题是我需要尽快生成 id,因为它在同一流程中创建的其他实体中用作软引用。

    我的解决方案是手动生成 id 并在流程的最后保留。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多