Java 具有 JPA 和 Bean 验证的唯一约束
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3495368/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Unique constraint with JPA and Bean Validation
提问by deamon
I'd like to have a @Unique
constraint with Bean Validation, but that is not provided by the standard. If I would use JPA's @UniqueConstraint
I wouldn't have a unique validation and error reporting mechanism.
我想对@Unique
Bean 验证有一个约束,但标准没有提供。如果我使用 JPA,@UniqueConstraint
我将没有独特的验证和错误报告机制。
Is there a way to define @Unique
as a Bean Validation constraint and combine it with JPA, such that JPA creates a column with an unique constraint and checks wheter a value is unique or not?
有没有办法定义@Unique
为 Bean 验证约束并将其与 JPA 结合,这样 JPA 创建一个具有唯一约束的列并检查值是否唯一?
采纳答案by Pascal Thivent
Unless you acquire a lock on a whole table, it is basically not possible to check for unicity using a SQL query (any concurrent transaction could modify data after a manual check but before the commit of the ongoing transaction). In other words, it isn't possible to implement a valid unique verification at the Java level and thus to provide a validation implementation. The only reliable way to check for unicity is while committing the transaction.
除非您获得整个表的锁,否则基本上不可能使用 SQL 查询检查唯一性(任何并发事务都可以在手动检查之后但在正在进行的事务提交之前修改数据)。换句话说,不可能在 Java 级别实现有效的唯一验证,从而提供验证实现。检查唯一性的唯一可靠方法是在提交事务时。
The BV spec summarizes it like this:
BV 规范是这样总结的:
Appendix D. Java Persistence 2.0 integration
Question: should we add @Unique that would map to @Column(unique=true)?
@Unique cannot be tested at the Java level reliably but could generate a database unique constraint generation. @Unique is not part of the BV spec today.
附录 D. Java Persistence 2.0 集成
问题:我们应该添加映射到@Column(unique=true) 的@Unique 吗?
@Unique 无法在 Java 级别可靠地进行测试,但可以生成数据库唯一约束生成。@Unique 今天不是 BV 规范的一部分。
So while I agree that it would be nice to have unique (and non null) constraint violations wrapped in a Bean Validation exception, this is currently not the case.
因此,虽然我同意在 Bean 验证异常中包含唯一(和非空)约束违规会很好,但目前情况并非如此。
References
参考
- Bean Validation specification (JSR 303)
- Question about validation and persistence constraints
- Bean 验证规范 (JSR 303)
- 关于验证和持久性约束的问题
回答by Mateusz Dymczyk
Well you CAN do it, but it's not trivial. The problem is: the validator requires database access to perform some queries to check, if the value you want to insert is already there or not. And this can't be really done from the validator, as it doesn't have access to the sessionFactory/session. Of course you could instantiate it (session/sessionFactory) inside the validator, but it's not a good coding practice.
好吧,你可以做到,但这不是微不足道的。问题是:验证器需要访问数据库来执行一些查询以检查您要插入的值是否已经存在。这不能从验证器真正完成,因为它无权访问 sessionFactory/session。当然,您可以在验证器中实例化它 (session/sessionFactory),但这不是一个好的编码习惯。
回答by dukethrash
You can make a validator read the JPA annotations and apply it. Here is somewhat of an example using spring validators that can be used as an idea to expand on.
您可以让验证器读取 JPA 注释并应用它。这是一个使用 spring 验证器的示例,可用作扩展的想法。
JPA JSR303 Spring Form Validation
You can also inject (@Inject
or Spring's @Autowired
) your session bean in a custom validator and the container should know how to wire it up. I only know this as a Spring example:
您还可以在自定义验证器中注入(@Inject
或 Spring 的@Autowired
)会话 bean,并且容器应该知道如何连接它。我只知道这是一个 Spring 示例:
import javax.validation.ConstraintValidator;
public class MyConstraintValidator implements ConstraintValidator {
@Autowired //@Inject
private Foo aDependency;
...
}
回答by Hardy
More information on how to implement a @Unique and the problematic around it can be found here - http://community.jboss.org/wiki/AccessingtheHibernateSessionwithinaConstraintValidator
关于如何实现 @Unique 及其周围问题的更多信息可以在这里找到 - http://community.jboss.org/wiki/AccessingtheHibernateSessionwithinaConstraintValidator