无限检查自定义 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;
    }