无限检查自定义 JSR303 注释
infinite check for custom JSR303 annotation
我正在尝试实现此 post 中所写的自定义注释,但出了点问题。当我试图将我的实体保存在数据库中时,它会使用我的自定义注释无限检查字段。我正在使用 wildfly 9.0.2
代码:
实体:
@Entity
@Table(name = "users")
@NamedQueries({
@NamedQuery(name = User.FIND_BY_LOGIN_AND_USERNAME,query = "SELECT u FROM User u WHERE u.userName = :username and u.password = :password"),
@NamedQuery(name = User.FIND_USER_BY_USERNAME,query = "SELECT u FROM User u WHERE u.userName = :username")
})
public class User implements Serializable{
public static final String FIND_BY_LOGIN_AND_USERNAME = "findByLoginAndPassword";
public static final String FIND_USER_BY_USERNAME = "findUserByUsername";
@Id
@GeneratedValue
private Long id;
@NotNull
@Size(min = 3,max = 64,message = "{model.User.login.message}")
@Username
@Column(name = "user_name",nullable = false,unique = true)
private String userName;
//...other fields...
//...constructors, getters and setters...
}
注解:
@Constraint(validatedBy = UsernameValidator.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD,ElementType.ANNOTATION_TYPE})
public @interface Username {
String message() default "Username already exists";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
验证者:
public class UsernameValidator implements ConstraintValidator<Username, String> {
@Inject
UserManager userManager;
@Override
public void initialize(Username constraintAnnotation) {
}
@Override
public boolean isValid(String username, ConstraintValidatorContext context) {
boolean isValid = !userManager.userExist(username);
return isValid;
}
}
用户管理器:
@Stateless
public class UserManager {
@PersistenceContext(unitName = "MySqlPU")
EntityManager em;
public void persist(User user){
em.persist(user);
}
public User findUserByLoginAndPassword(String username, String password) {
try {
return em.createNamedQuery(User.FIND_BY_LOGIN_AND_USERNAME, User.class)
.setParameter("username",username)
.setParameter("password",password)
.getSingleResult();
} catch (NoResultException e){
return null;
}
}
public boolean userExist(String username) {
try {
em.createNamedQuery(User.FIND_USER_BY_USERNAME, User.class)
.setParameter("username", username)
.getSingleResult();
} catch (NoResultException e) {
return false;
}
return true;
}
}
link 到 server.log (snip2code)
提前致谢!
所以问题是,当我从我的验证器调用 userExist(String username)
时,它需要父事务以及 @maress 所说的,进入无限循环。我通过在 userExist
方法中禁用事务来解决这个问题。所以现在有了这个更改代码就可以工作了
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public boolean userExist(String username) {
try {
em.createNamedQuery(User.FIND_USER_BY_USERNAME, User.class)
.setParameter("username", username)
.getSingleResult();
} catch (NoResultException e) {
return false;
}
return true;
}
我正在尝试实现此 post 中所写的自定义注释,但出了点问题。当我试图将我的实体保存在数据库中时,它会使用我的自定义注释无限检查字段。我正在使用 wildfly 9.0.2
代码:
实体:
@Entity
@Table(name = "users")
@NamedQueries({
@NamedQuery(name = User.FIND_BY_LOGIN_AND_USERNAME,query = "SELECT u FROM User u WHERE u.userName = :username and u.password = :password"),
@NamedQuery(name = User.FIND_USER_BY_USERNAME,query = "SELECT u FROM User u WHERE u.userName = :username")
})
public class User implements Serializable{
public static final String FIND_BY_LOGIN_AND_USERNAME = "findByLoginAndPassword";
public static final String FIND_USER_BY_USERNAME = "findUserByUsername";
@Id
@GeneratedValue
private Long id;
@NotNull
@Size(min = 3,max = 64,message = "{model.User.login.message}")
@Username
@Column(name = "user_name",nullable = false,unique = true)
private String userName;
//...other fields...
//...constructors, getters and setters...
}
注解:
@Constraint(validatedBy = UsernameValidator.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD,ElementType.ANNOTATION_TYPE})
public @interface Username {
String message() default "Username already exists";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
验证者:
public class UsernameValidator implements ConstraintValidator<Username, String> {
@Inject
UserManager userManager;
@Override
public void initialize(Username constraintAnnotation) {
}
@Override
public boolean isValid(String username, ConstraintValidatorContext context) {
boolean isValid = !userManager.userExist(username);
return isValid;
}
}
用户管理器:
@Stateless
public class UserManager {
@PersistenceContext(unitName = "MySqlPU")
EntityManager em;
public void persist(User user){
em.persist(user);
}
public User findUserByLoginAndPassword(String username, String password) {
try {
return em.createNamedQuery(User.FIND_BY_LOGIN_AND_USERNAME, User.class)
.setParameter("username",username)
.setParameter("password",password)
.getSingleResult();
} catch (NoResultException e){
return null;
}
}
public boolean userExist(String username) {
try {
em.createNamedQuery(User.FIND_USER_BY_USERNAME, User.class)
.setParameter("username", username)
.getSingleResult();
} catch (NoResultException e) {
return false;
}
return true;
}
}
link 到 server.log (snip2code)
提前致谢!
所以问题是,当我从我的验证器调用 userExist(String username)
时,它需要父事务以及 @maress 所说的,进入无限循环。我通过在 userExist
方法中禁用事务来解决这个问题。所以现在有了这个更改代码就可以工作了
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public boolean userExist(String username) {
try {
em.createNamedQuery(User.FIND_USER_BY_USERNAME, User.class)
.setParameter("username", username)
.getSingleResult();
} catch (NoResultException e) {
return false;
}
return true;
}