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



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

所以我试了:

@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);
  }

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

你能告诉我为什么吗?

顺便说一句:

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

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

这工作,但不是真的很酷!

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

从规格:

非常非正式地说,利斯科夫替代原理是这样说的当使用给定类型T时,应该可以用T的子类型S("行为亚型")。如果S重写/实现来自T和S的方法将加强该方法的先决条件(例如,通过添加参数约束)这个原则将是当客户端代码在T上正常工作时可能会失败如果S覆盖/实现了来自T和的方法S削弱了方法的后置条件违反了。然而,S可以通过添加返回值约束),作为针对T的客户端代码仍然可以对付s。

我认为您的第二个示例实际上应该可以工作,但是,我不熟悉NetBeans AbstractFacade。我的猜测是对checkedCreate(entity);的调用没有通过代理实例,因此没有被拦截。也许您可以发布所涉及的类的完整代码?什么类型的类包含这些方法?会话bean?

我也遇到过同样的问题。

我的代码是这样的:
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);
}

您应该这样做:

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

谢谢Hardy。希望我能把它们贴出来:

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);
  }
}

最新更新