Java EE参数约束配置奇怪的行为

时间:2014-03-23 16:15:16

标签: java java-ee bean-validation facade

我试图在standrd AbstractFacade的创建和编辑方法上添加参数约束配置(bean验证)(由NetBeans生成)。

所以我试过了:

@Override
public void create(@WkTeilnahmePlanedResult  WkTeilnahme entity) {
   super.create(entity);
}

这返回了消息

  

重写另一个方法的方法不得更改参数   约束配置   何时将其部署到Glassfish 4

所以接下来的尝试是

  @Override
  public void create(WkTeilnahme entity) {
    checkedCreate(entity);
  }


  private void checkedCreate(@WkTeilnahmePlanedResult WkTeilnahme entity) {
    super.create(entity);
  }

部署没有任何问题......但验证器永远不会被调用。

你能告诉我为什么吗?

BTW:

  @Override
  public void create(WkTeilnahme entity) {
    throw new UnsupportedOperationException(
            "Create not supported! Use checkedCreate() instead!");
  }


  public void checkedCreate(@WkTeilnahmePlanedResult WkTeilnahme entity) {
    super.create(entity);
  }

这可行,但不是很酷!

4 个答案:

答案 0 :(得分:1)

关于您的第一次尝试,它不起作用,因为Bean Validation约束必须遵循Liskov Substitution Principle。另请参阅相关Bean验证规范部分 - http://beanvalidation.org/1.1/spec/#constraintdeclarationvalidationprocess-methodlevelconstraints-inheritance

来自规范:

  

非正式地说,Liskov替代原则说明了这一点   在使用给定类型T的情况下,应该可以用T代替   T的子类型S("行为子类型")。如果S覆盖/实现   T和S的方法将加强方法的前提条件   (例如,通过添加参数约束)这个原则将是   因为客户端代码正常工作而违反T可能会失败   对S的工作。如果S覆盖/实现T和T的方法   S削弱了该原则的方法后置条件   侵犯。然而,S可能会加强方法的后置条件(通过   添加返回值约束),作为针对T的客户端代码   仍然会对抗S。

我认为您的第二个示例应该可行,但是,我不熟悉NetBeans AbstractFacade 。我的猜测是对 checkedCreate(entity); 的调用不是通过代理实例进行的,因此不会被截获。也许你可以发布相关课程的完整代码?什么类型的类包含这些方法?会话bean?

答案 1 :(得分:0)

谢谢哈代。 舒尔我可以张贴他们:

package at.wima.member.facade;

import java.util.List;
import javax.persistence.EntityManager;

public abstract class AbstractFacade<T> {
  private Class<T> entityClass;

  public AbstractFacade(Class<T> entityClass) {
    this.entityClass = entityClass;
  }

  protected abstract EntityManager getEntityManager();

  public void create(T entity) {
    getEntityManager().persist(entity);
  }

  public T edit(T entity) {
    return getEntityManager().merge(entity);
  }

  public void remove(T entity) {
    getEntityManager().remove(getEntityManager().merge(entity));
  }

  public T find(Object id) {
    return getEntityManager().find(entityClass, id);
  }

  public List<T> findAll() {
    javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
    cq.select(cq.from(entityClass));
    return getEntityManager().createQuery(cq).getResultList();
  }

  public List<T> findRange(int[] range) {
    javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
    cq.select(cq.from(entityClass));
    javax.persistence.Query q = getEntityManager().createQuery(cq);
    q.setMaxResults(range[1] - range[0]);
    q.setFirstResult(range[0]);
    return q.getResultList();
  }

  public int count() {
    javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
    javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
    cq.select(getEntityManager().getCriteriaBuilder().count(rt));
    javax.persistence.Query q = getEntityManager().createQuery(cq);
    return ((Long) q.getSingleResult()).intValue();
  }

}

和子类

package at.wima.member.facade;

import at.wima.member.entity.*;
import at.wima.member.validations.*;
import java.util.*;
import javax.ejb.Stateless;
import javax.persistence.*;


@Stateless
public class WkTeilnahmeFacade extends AbstractFacade<WkTeilnahme> {

  @PersistenceContext(unitName = "memberPu")
  private EntityManager em;


  public WkTeilnahme findByKey(Mandant mandant, Wettkampf wettkampf,
                               Person person) {
    Query query = em.createNamedQuery("wkTeilnahmeFindByKey");
    query.setParameter("mandant", mandant);
    query.setParameter("wettkampf", wettkampf);
    query.setParameter("person", person);
    List rl = query.getResultList();

    if (rl.size() <= 0) {
      return null;
    }
    return (WkTeilnahme) (rl.get(0));
  }


  public List<WkTeilnahme> findAllSort(Mandant mandant) {
    Query query = em.createNamedQuery("wkTeilnahmeFindAllSort");
    query.setParameter("mandant", mandant);
    return query.getResultList();
  }


  public List<WkTeilnahme> findByWettkampf(Mandant mandant, Wettkampf wettkampf) {
    Query query = em.createNamedQuery("wkTeilnahmeFindByWettkampf");
    query.setParameter("mandant", mandant);
    query.setParameter("wettkampf", wettkampf);
    return query.getResultList();
  }


  @Override
  public void create(WkTeilnahme entity) {
    throw new UnsupportedOperationException(
            "Create not supported! Use checkedCreate() instead!");
  }


  public void checkedCreate(@WkTeilnahmePlanedResult WkTeilnahme entity) {
    super.create(entity);
  }


  @Override
  public WkTeilnahme edit(WkTeilnahme entity) {
    throw new UnsupportedOperationException(
            "Edit not supported! Use checkedEdit() instead!");
  }


  public WkTeilnahme checkedEdit(@WkTeilnahmePlanedResult WkTeilnahme entity) {
     return super.edit(entity);
  }


  @Override
  protected EntityManager getEntityManager() {
    return em;
  }


  public WkTeilnahmeFacade() {
    super(WkTeilnahme.class);
  }
}

答案 2 :(得分:0)

您应该执行以下操作:

inteface Test {
   void create(@WkTeilnahmePlanedResult  WkTeilnahme entity);
}

@Validated
class TestImpl implement Test {
    @Override
    public void create(WkTeilnahme entity) {
       super.create(entity);
    }
}

答案 3 :(得分:0)

我遇到了同样的问题。

我的代码是这样的:

public interface SomeService{
    List<Object> getObjects(Integer id);
}

public class SomeServiceImpl implements SomeService{
    @Override
    public List<Object> getObjects(@NotNull Integer id) { ... }
}

我在服务中添加了相同的注解,问题已经解决:

public interface SomeService{
    List<Object> getObjects(@NotNull Integer id);
}