验证器接收空对象 - 为什么?
Validator receiving null objects ¿why?
首先感谢所有试图帮助我解决这个问题的人:我正在尝试验证至少包含一个元素的列表,如果我检查使用
Set<ConstraintViolation<Object>> constraintViolations = VALIDATOR.validate(anObj);
约束工作正常,但是当我尝试坚持时,具有一个元素的对象再次通过并且列表为空...
这是 class 列表的一部分:
public class Team implements Serializable {
//...
@AtLeastOneNotNull
@ManyToMany
@JoinTable(
name="teams_players"
, joinColumns={
@JoinColumn(name="id_team")
}
, inverseJoinColumns={
@JoinColumn(name="id_player")
}
)
private List<Player> players;
//...
}
验证者:
public class AtLeastOneNotNullValidator implements ConstraintValidator<AtLeastOneNotNull, List<?>> {
@Override
public void initialize(AtLeastOneNotNull constraint) {
}
@Override
public boolean isValid(List<?> aCollection, ConstraintValidatorContext aConstraintValidatorContext) {
if(aCollection == null || aCollection.isEmpty())
return false;
else
return true;
}
}
注解:
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = AtLeastOneNotNullValidator.class)
public @interface AtLeastOneNotNull {
String message() default "{[ERROR] Collection must have at least one element}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
测试class:
public class TeamDAOTest {
private static Validator VALIDATOR;
TeamTestHelper teamTestHelper = null;
TeamDAO teamDaoTest = null;
@Before
public void initTestClass() {
teamDaoTest = new TeamDAO();
teamTestHelper = new TeamTestHelper();
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
VALIDATOR = factory.getValidator();
}
@After
public void endTestClass() {
}
@Test
public void savingRightTeam() {
Team testTeam = teamTestHelper.getTeamOK();
// Set<ConstraintViolation<Team>> constraintViolations = VALIDATOR.validate(testTeam);
//
// assertEquals(0, constraintViolations.size());
//
assertEquals("Inserting right Team", true, teamDaoTest.updateEntity(testTeam));
}
@Test
public void savingWrongTeam() {
Team testTeam = teamTestHelper.getTeamKO_WithoutPlayers();
// Set<ConstraintViolation<Team>> constraintViolations = VALIDATOR.validate(testTeam);
//
// assertEquals(1, constraintViolations.size());
assertEquals("Inserting empty Team", false, teamDaoTest.updateEntity(testTeam));
}
}
最后,当我 运行 这个
首先,您可以看到使用具有一个元素的列表创建的团队。
注:helper先创建一个player并持久化,然后添加到一个team中return,这就是我们看到的Team。
在第二步中,当它试图持久化元素并通过验证器时,列表为空...为什么?
最后,当然,对于空列表,merge 方法会抛出异常:
知道会发生什么吗?我不知道为什么会这样,正如你所看到的,我评论了其他行,测试通过了,但是当我尝试更新时,它似乎是另一个对象,或者对象再次实例化
再次感谢大家
编辑:
Team 对象中的 getPlayer() 和 addPlayer() 方法:
public List<Player> getPlayers() {
if(this.players == null)
this.players = new ArrayList<Player>();
return this.players;
}
public boolean addPlayer(Player aPlayer){
if(!getPlayers().contains(aPlayer)){
this.players.add(aPlayer);
return true;
}
else return false;
}
编辑 2:DAO,如您所见,现在我不需要 TeamDAO 中更具体的方法
public class TeamDAO extends AbstractDAOLayer<Team> {
}
AbstractDAOLayer 中的 UpdateEntity 方法
public boolean updateEntity(T anObject){
try{
this.beginTransaction();
this.entityManager.merge(anObject);
this.finishtTransaction();
return true;
}
catch(Exception e){
return false;
}
}
请检查this。该问题与 BV 无关,而是与具有多对多关系的 jpa 合并语义有关。
首先感谢所有试图帮助我解决这个问题的人:我正在尝试验证至少包含一个元素的列表,如果我检查使用
Set<ConstraintViolation<Object>> constraintViolations = VALIDATOR.validate(anObj);
约束工作正常,但是当我尝试坚持时,具有一个元素的对象再次通过并且列表为空...
这是 class 列表的一部分:
public class Team implements Serializable {
//...
@AtLeastOneNotNull
@ManyToMany
@JoinTable(
name="teams_players"
, joinColumns={
@JoinColumn(name="id_team")
}
, inverseJoinColumns={
@JoinColumn(name="id_player")
}
)
private List<Player> players;
//...
}
验证者:
public class AtLeastOneNotNullValidator implements ConstraintValidator<AtLeastOneNotNull, List<?>> {
@Override
public void initialize(AtLeastOneNotNull constraint) {
}
@Override
public boolean isValid(List<?> aCollection, ConstraintValidatorContext aConstraintValidatorContext) {
if(aCollection == null || aCollection.isEmpty())
return false;
else
return true;
}
}
注解:
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = AtLeastOneNotNullValidator.class)
public @interface AtLeastOneNotNull {
String message() default "{[ERROR] Collection must have at least one element}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
测试class:
public class TeamDAOTest {
private static Validator VALIDATOR;
TeamTestHelper teamTestHelper = null;
TeamDAO teamDaoTest = null;
@Before
public void initTestClass() {
teamDaoTest = new TeamDAO();
teamTestHelper = new TeamTestHelper();
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
VALIDATOR = factory.getValidator();
}
@After
public void endTestClass() {
}
@Test
public void savingRightTeam() {
Team testTeam = teamTestHelper.getTeamOK();
// Set<ConstraintViolation<Team>> constraintViolations = VALIDATOR.validate(testTeam);
//
// assertEquals(0, constraintViolations.size());
//
assertEquals("Inserting right Team", true, teamDaoTest.updateEntity(testTeam));
}
@Test
public void savingWrongTeam() {
Team testTeam = teamTestHelper.getTeamKO_WithoutPlayers();
// Set<ConstraintViolation<Team>> constraintViolations = VALIDATOR.validate(testTeam);
//
// assertEquals(1, constraintViolations.size());
assertEquals("Inserting empty Team", false, teamDaoTest.updateEntity(testTeam));
}
}
最后,当我 运行 这个
首先,您可以看到使用具有一个元素的列表创建的团队。
注:helper先创建一个player并持久化,然后添加到一个team中return,这就是我们看到的Team。
在第二步中,当它试图持久化元素并通过验证器时,列表为空...为什么?
最后,当然,对于空列表,merge 方法会抛出异常:
知道会发生什么吗?我不知道为什么会这样,正如你所看到的,我评论了其他行,测试通过了,但是当我尝试更新时,它似乎是另一个对象,或者对象再次实例化
再次感谢大家
编辑:
Team 对象中的 getPlayer() 和 addPlayer() 方法:
public List<Player> getPlayers() {
if(this.players == null)
this.players = new ArrayList<Player>();
return this.players;
}
public boolean addPlayer(Player aPlayer){
if(!getPlayers().contains(aPlayer)){
this.players.add(aPlayer);
return true;
}
else return false;
}
编辑 2:DAO,如您所见,现在我不需要 TeamDAO 中更具体的方法
public class TeamDAO extends AbstractDAOLayer<Team> {
}
AbstractDAOLayer 中的 UpdateEntity 方法
public boolean updateEntity(T anObject){
try{
this.beginTransaction();
this.entityManager.merge(anObject);
this.finishtTransaction();
return true;
}
catch(Exception e){
return false;
}
}
请检查this。该问题与 BV 无关,而是与具有多对多关系的 jpa 合并语义有关。