【问题标题】:hibernate validation doesn't happen on persist in database在数据库中持久化时不会发生休眠验证
【发布时间】:2015-05-19 21:55:25
【问题描述】:

我有以下会话工厂配置:

     <session-factory>
        <property name="javax.persistence.validation.group.pre-persist">javax.validation.groups.Default</property>
        <property name="javax.persistence.validation.group.pre-update">javax.validation.groups.Default</property>
        <property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
        <property name="hibernate.showSql">true</property>
        <property name="hbm2ddl.auto">validate</property>
        <mapping class="com.terminal.domain.Terminal"/>
        ...
    </session-factory>

终端类:

@Entity
@Table(name = "terminal")
public class Terminal {
    @Column(name = "cost")
    @Min(100)
    private Long cost;
    // get and set
}

我的服务方法中有以下代码:

Terminal terminal = new Terminal();
terminal.setCost(98L);
session.save(terminal);

当我调用它时,terminal 表中添加了新行。
预期结果:验证异常和新行未添加到terminal 表中。

为什么实际结果与预期不同?

附言

据我了解,它应该开箱即用 http://docs.jboss.org/hibernate/validator/4.1/reference/en-US/html/validator-checkconstraints.html#validator-checkconstraints-orm-hibernateevent

附言

hibernate 东西依赖:

       <dependency>
            <groupId>javax.persistence</groupId>
            <artifactId>persistence-api</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>3.3.2.GA</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-annotations</artifactId>
            <version>3.3.1.GA</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-commons-annotations</artifactId>
            <version>3.3.0.ga</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>4.2.0.Final</version>
        </dependency>

分辨率

执行以下步骤后问题消失:

1.迁移库版本:

hibernate-core: 3.3.2.GA -> 4.3.10.Final
hibernate-annotations: 3.3.1.GA -> 3.5.6-Final
hibernate-commons-annotations: 3.3.0.ga -> 3.2.0.Final
hibernate-validator: 4.2.0.Final -> 5.1.3.Final

移除依赖:

<dependency>
    <groupId>javax.persistence</groupId>
    <artifactId>persistence-api</artifactId>
    <version>1.0</version>
</dependency>

2.在配置中替换

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
     <property name="sessionFactory" ref="sessionFactory"/>
</bean

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
     <property name="sessionFactory" ref="sessionFactory"/>
 </bean

3. 对于会话工厂:

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation">
            <value>classpath:hibernate-test.cfg.xml</value>
        </property>
        <property name="configurationClass">
            <value>org.hibernate.cfg.AnnotationConfiguration</value>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.connection.charSet">UTF-8</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hbm2ddl.auto">create-drop</prop>
            </props>
        </property>
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation">
            <value>classpath:hibernate-test.cfg.xml</value>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.connection.charSet">UTF-8</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hbm2ddl.auto">create-drop</prop>
            </props>
        </property>
    </bean>

4.会话工厂配置:

<session-factory>
        <property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
        <property name="hibernate.showSql">true</property>
        <property name="hbm2ddl.auto">validate</property>
        ...//classes mapping
</session-factory>

实际上我不明白哪个具体步骤解决了我的问题,但复杂的是它确实有效

【问题讨论】:

  • 至少要了解一切是否正常.. 如果你做这样的事情.. Terminal terminal = new Terminal();终端.setCost(98L); ValidatorFactory 工厂 = Validation.buildDefaultValidatorFactory();验证器验证器 = factory.getValidator(); Set> constraintViolations = validator.validate(terminal); if (constraintViolations != null && constraintViolations.size() > 0) { // 在这里处理你的异常 } else { session.save(terminal); } 是显式验证器考虑的注释吗?
  • 您找到解决方案了吗?
  • @Rohit 是的,主题已更新
  • @witchedwiz 主题已更新
  • 我认为事务管理器的变化起到了作用

标签: java spring hibernate persistence hibernate-validator


【解决方案1】:

您引用的配置属性适用于 JPA。如果您使用的是 JPA API,它应该可以工作。看起来您正在使用本机 Hibernate ORM Session API。您需要使用EntityManager API。

【讨论】:

  • 对不起,这个愚蠢的问题,但是如何理解我使用 JPA Api 或本地休眠会话 api?
【解决方案2】:

您需要使用 Hibernate 验证器。 这里是maven神器

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.3.Final</version>

这里是入门文档。

http://hibernate.org/validator/documentation/getting-started/

【讨论】:

  • 你认为我使用了错误版本的休眠验证器吗?
  • 检查您的版本有哪些功能,也许用于验证的@annotation 确实不适用于您的版本
  • 如果您没有任何依赖限制,我将尝试使用此版本并按照我附加的文档检查是否有效。在我们的例子中,它就像一个魅力
  • 没有。应用您的建议后,我没有看到任何变化
【解决方案3】:

如果您使用的是 JPA,则需要添加以下 EntityManager 侦听器:

<event type="pre-update">
    <listener class="org.hibernate.cfg.beanvalidation.BeanValidationEventListener"/>
</event>
<event type="pre-insert">
    <listener class="org.hibernate.cfg.beanvalidation.BeanValidationEventListener"/>
</event>
<event type="pre-delete">
    <listener class="org.hibernate.cfg.beanvalidation.BeanValidationEventListener"/>
</event>

并且还要添加以下属性:

<property name="javax.persistence.validation.mode">
  ddl, callback
</property>

如果您使用的是 Hibernate 特定配置,带有hibernate.cfg.xml,那么配置变为:

 <event type="pre-update">
   <listener class="org.hibernate.cfg.beanvalidation.BeanValidationEventListener"/>
</event>
<event type="pre-insert">
    <listener class="org.hibernate.cfg.beanvalidation.BeanValidationEventListener"/>
</event>
<event type="pre-delete">
    <listener class="org.hibernate.cfg.beanvalidation.BeanValidationEventListener"/>
</event>

【讨论】:

  • 当我将事件添加到我的 hibernate.cfg.xml 中时,我看到以下错误“元素类型 'session-factory' 的内容必须匹配 '(property*, mapping*,class- cache|collection-cache), event*, listener)'。”
  • 也许我使用了不一致的休眠版本?
  • 那些用于persistence.xml。
  • 嗯,对不起,我不是休眠大师。我只有冬眠。 cfg.xml
  • 看起来你复制了与 JPA 相同的配置。我看到旧错误
【解决方案4】:

您必须使用 org.hibernate.validator.constraints 包中提供的 @Range 注释。

https://docs.jboss.org/hibernate/validator/4.1/api/org/hibernate/validator/constraints/Range.html

import org.hibernate.validator.constraints.Range;
...

@Entity
@Table(name = "terminal")
public class Terminal {
    @Column(name = "cost")
    @Range(min=100, message="Should be of min length 10.")
    private Long cost;
    // get and set
}

我没有编译这段代码。所以它们可能是语法错误。

【讨论】:

  • 不幸的是,在您的建议应用后,我没有看到行为纠正
【解决方案5】:

您似乎在混合 JPA 和 Hibernate 特定的 api。在您的配置文件中删除:

<property name="javax.persistence.validation.group.pre-persist">javax.validation.groups.Default</property>
<property name="javax.persistence.validation.group.pre-update">javax.validation.groups.Default</property>

并添加

   <event type="pre-update">
     <listener class="org.hibernate.cfg.beanvalidation.BeanValidationEventListener"/>
   </event>
   <event type="pre-insert">
     <listener class="org.hibernate.cfg.beanvalidation.BeanValidationEventListener"/>
   </event>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-19
    • 1970-01-01
    相关资源
    最近更新 更多