我试图在标准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);
}
}