java - JPA: Find by Interface instead of Implementation -
i want use find method interface, instead of using implementation.
that said here code:
public goods findgoods(long goodsid) { return this.jpaapi.withtransaction(()->{ goods goods = null; try{ entitymanager em = this.jpaapi.em(); query query = em.createquery("select g goods g id=:id", goods.class); query.setparameter("id", goodsid); goods = (goods) query.getsingleresult(); }catch (exception e) { // todo: handle exception e.printstacktrace(); } return goods; }); }
my entity:
@entity(name = "goods") @table(name = "goods") @inheritance(strategy = inheritancetype.single_table) public class goodsimp implements goods, serializable { .. }
my interface:
@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 { .. }
error:
java.lang.illegalargumentexception: unable locate 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) @ play.db.jpa.defaultjpaapi.lambda$withtransaction$3(defaultjpaapi.java:197)
my doubt why have issue, if when use query statement works fine interface.
this works:
@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 goods g", goods.class); goods = query.getresultlist(); } catch (exception e) { // todo: handle exception e.printstacktrace(); } return goods; }); }
the entitymanager
method createquery
used declared as:
<t> typedquery<t> createquery(string qlstring, class<t> resultclass)
the only reason class<t> resultclass
parameter infer type of t
, write:
list<goods> listofgoods = em.createquery("select g goods g id=:id", goods.class).getresultlist();
without getting compiler warnings. resultclass
parameter certainly not telling entitymanager
entity type querying for. done select g goods g
part of query, , incidentally, goods
alias entity goodsimpl
(you annotate goodsimpl
entity @entity(name = "bads")
, select b bads b
work).
now, if understand correctly, you're asking why call em.find(entityclass, primarykey)
fails when goods.class
used entityclass
. can find answer in javadoc entitymanager
, in find
said throw:
illegalargumentexception - if first argument not denote entity type
an entity type is, unsuprisingly, class annotated @entity
.
if you're asking why way implemented, answer pretty simple. interface can implemented several classes. suppose had multiple entity classes implementing goods
, each own table , own id. there no reason ids not overlap across these different entities. how jpa supposed know of these entities you're hoping get?
Comments
Post a Comment