我想将find方法与接口一起使用,而不是与实现一起使用。
这就是我的代码:
public Goods findGoods(Long goodsId) {
return this.jpaApi.withTransaction(()->{
Goods goods = null;
try{
EntityManager em = this.jpaApi.em();
Query query = em.createQuery("select g from Goods g where id=:id", Goods.class);
query.setParameter("id", goodsId);
goods = (Goods) query.getSingleResult();
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return goods;
});
}
我的实体:
@Entity(name = "Goods")
@Table(name = "GOODS")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class GoodsImp implements Goods, Serializable {
..
}
我的界面:
@JsonTypeInfo(include = JsonTypeInfo.As.PROPERTY, property = "type",
use = Id.NAME, defaultImpl = GoodsImp.class, visible = true)
@JsonSubTypes({ @Type(value = ProductImp.class, name = "product"),
@Type(value = ServiceImp.class, name = "service") })
@ImplementedBy(GoodsImp.class)
public interface Goods {
..
}
错误:
java.lang.IllegalArgumentException:无法找到persister:interfaces.Goods 在org.hibernate.internal.SessionImpl.find(SessionImpl.java:3422) 在org.hibernate.internal.SessionImpl.find(SessionImpl.java:3365) 在repository.JPAGoodsRepository.lambda $ deleteGoods $ 2(JPAGoodsRepository.java:58) at play.db.jpa.DefaultJPAApi.lambda $ withTransaction $ 3(DefaultJPAApi.java:197)
我怀疑这就是为什么我有这个问题,如果我使用Query语句时可以正常使用该接口。
这有效:
@Override
public Collection<Goods> getAllGoods() {
return this.jpaApi.withTransaction(() -> {
Collection<Goods> goods = null;
try {
EntityManager em = this.jpaApi.em();
Query query = em.createQuery("Select g from Goods g", Goods.class);
goods = query.getResultList();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return goods;
});
}
答案 0 :(得分:2)
您使用的EntityManager
方法createQuery
声明为:
<T> TypedQuery<T> createQuery(String qlString, Class<T> resultClass)
Class<T> resultClass
参数的唯一原因是推断T
的类型,以便您可以写:
List<Goods> listOfGoods = em.createQuery("select g from Goods g where id=:id", Goods.class).getResultList();
没有收到编译器警告。 resultClass
参数肯定不是告诉entityManager
您要查询的实体类型。这是由查询的select g from Goods g
部分完成的,顺便提一下,Goods
是实体GoodsImpl
的别名(您可以使用{{1}注释GoodsImpl
实体}和@Entity(name = "Bads")
也可以)。
现在,如果我理解正确,那么当select b from Bads b
用于em.find(entityClass, primaryKey)
时,您就会问为什么通话Goods.class
失败了。您可以在entityClass
的javadoc中找到答案,其中EntityManager
被称为:
IllegalArgumentException - 如果第一个参数不表示实体类型
实体类型是一个带有find
注释的类,毫无疑问。
如果你问为什么这就是它的实现方式,那么答案就很简单了。接口可以由几个类实现。假设您有多个实现@Entity
的实体类,每个实体类都有自己的表和自己的id。没有理由不在这些不同的实体之间重叠。 JPA应该如何知道您希望获得哪些实体?