Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JPA ArgumentException在急切共享关系oneToOne上执行联接获取时出错_Jpa_Join_Fetch_Openjpa - Fatal编程技术网

JPA ArgumentException在急切共享关系oneToOne上执行联接获取时出错

JPA ArgumentException在急切共享关系oneToOne上执行联接获取时出错,jpa,join,fetch,openjpa,Jpa,Join,Fetch,Openjpa,我面临着一个问题,与加入获取和渴望的关系 我有以下实体关系: 实体A扩展了抽象实体E 抽象实体E与实体C具有一对一的双向关系,具有急切获取类型 实体A与实体B有一家公司的关系 实体B扩展了抽象实体E(因此与C也有oneToOne关系) 实体C与抽象实体E的关系相反 执行简单的namedQuery时,如 SELECT a FROM A a WHERE a.key = :key 如果参数'key'是字符串类型,那么我就没有问题了。从检索到的实体A访问子实体B时,按其预期执行子请求 但是,如果我向n

我面临着一个问题,与加入获取和渴望的关系

我有以下实体关系:

实体A扩展了抽象实体E

抽象实体E与实体C具有一对一的双向关系,具有急切获取类型

实体A与实体B有一家公司的关系

实体B扩展了抽象实体E(因此与C也有oneToOne关系)

实体C与抽象实体E的关系相反

执行简单的namedQuery时,如

SELECT a FROM A a WHERE a.key = :key
如果参数'key'是字符串类型,那么我就没有问题了。从检索到的实体A访问子实体B时,按其预期执行子请求

但是,如果我向namedQuery添加一个JOIN FETCH:

SELECT a FROM A a JOIN FETCH a.entitiesB WHERE a.key = :key
我获得以下错误堆栈跟踪:

javax.ejb.EJBTransactionRolledbackException: The transaction has been marked rollback only because the bean encountered a non-application exception :javax.ejb.EJBTransactionRolledbackException : The transaction has been marked rollback only because the bean encountered a non-application exception :org.apache.openjpa.persistence.ArgumentException : The specified parameter of type "class org.apache.openjpa.util.LongId" is not a valid query parameter.
at org.apache.openejb.core.ivm.BaseEjbProxyHandler.convertException(BaseEjbProxyHandler.java:345)
at org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:283)
... 
Caused by: <openjpa-2.2.0-r422266:1244990 nonfatal user error> org.apache.openjpa.persistence.ArgumentException: The specified parameter of type "class org.apache.openjpa.util.LongId" is not a valid query parameter.
FailedObject: SELECT relation FROM Relation relation JOIN FETCH relation.accounts WHERE relation.key = :key [java.lang.String]
at org.apache.openjpa.jdbc.sql.DBDictionary.setUnknown(DBDictionary.java:1458)
at org.apache.openjpa.jdbc.sql.SQLBuffer.setParameters(SQLBuffer.java:544)
at org.apache.openjpa.jdbc.sql.SQLBuffer.prepareStatement(SQLBuffer.java:453)
at org.apache.openjpa.jdbc.sql.SQLBuffer.prepareStatement(SQLBuffer.java:429)
at org.apache.openjpa.jdbc.sql.SelectImpl.prepareStatement(SelectImpl.java:479)
... 
抽象实体类

Dao样本

TypedQuery query=createNamedQuery(“findDetails”,A.class);
query.setParameter(“customKey”,queryParam);
List AEntiesFound=query.getResultList();

提前感谢您的帮助。

我想我找到了问题所在。这是由于openJPA不真正支持的映射,如果我们参考

最后,我有两个解决方案:


解决方案1(简单的一个):

  • 将抽象实体类上的fetch类型更改为LAZY
  • 添加提取组并更新每个相关名称查询或代码
优势:

  • 快速解决方案,对现有代码没有太大影响
缺点:

  • 必须调查新惰性字段的使用情况以及相关查询的更新,因为它现在将根据getter(如果不是从更新的namedquerys)惰性加载
  • 使用Junit和dynamic enhancement运行测试时,在使用这种映射(抽象和表每类继承类型)对NamedQuery执行连接获取时,仍然会抛出NPE

解决方案2:修改映射

  • 从抽象实体中删除继承的用法(事实上没有业务用法)并替换为@MappedSuperClass(因此删除@entity和@Inheritation)
  • 添加接口并定义属性的getter/setter
  • 将此接口实现到抽象实体类中,以便子类必须实现getter/setter(以及相关属性和映射)
  • 将这些急切对象的目标实体上的反向关系类型从抽象类类型更改为新接口类型
  • 最后,将映射的实现、属性的getter和setter从抽象实体类移动到所有子实体类
优势:

  • 没有其他异常(也没有由于旧映射和动态类增强而导致的NPE)
  • 更强大的解决方案,因为有更多机会避免由于openJPA对旧映射样式的限制而导致的进一步异常
缺点:

  • 更多修改
  • 由于接口而不是目标实体类中的抽象类类型,开发人员的可读性可能会降低
@Entity
@Table(name = "TABLE_A")
@Access(AccessType.FIELD)
@NamedQueries({
   @NamedQuery(name = "findADetails", query = "SELECT a FROM A a WHERE a.customKey.key     = :customKey")})
public class A extends abstractEntity {

   @Embedded
   private CustomEmbeddedKey customKey;

   @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "entityA")
   private List<B> bEntities;

   ...
}
@Entity
@Table(name = "TABLE_B")
@Access(AccessType.FIELD)
public class B extends abstractEntity {

   @ManyToOne(fetch = FetchType.LAZY, targetEntity = A.class)
   @JoinColumn(name = "FK_A_ID")
   private A entityA;

   ...
}
@Entity
@Access(AccessType.FIELD)
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@SequenceGenerator(name = "TOTO_ID_SEQ", sequenceName = "TOTO_ID_SEQ", initialValue = 1, allocationSize = 1)
public abstract class abstractEntity {

   @Id
   @Column(name = "ID")
   @GeneratedValue(generator = "TOTO_ID_SEQ", strategy = GenerationType.SEQUENCE)
   private Long id;

   @OneToOne(mappedBy = "...", fetch = FetchType.EAGER)
   private C anotherEntity;

   @OneToMany(mappedBy = "...", fetch = FetchType.LAZY)
   private List<D> anotherEntities;

   ...

}
@Embeddable
@Access(AccessType.FIELD)
public class CustomEmbeddedKey {

   @Column(name = "...", length = ...)
   private String key;

   ...
}
TypedQuery<A> query = createNamedQuery("findADetails", A.class);
  query.setParameter("customKey", queryParam);
  List<A> aEntitiesFound = query.getResultList();