JPA,打开 JPA OneToMany - FailedObject

Posted

技术标签:

【中文标题】JPA,打开 JPA OneToMany - FailedObject【英文标题】:JPA, Open JPA OneToMany - FailedObject 【发布时间】:2019-04-04 18:24:28 【问题描述】:

我正在做简单的 OneToMany JPA 概念并使用 Junit 进行验证。获取实体时出现 FailedObject 错误(oneToMany 关系) .我正在使用 Oen JPA 最新版本,TomEE 8。

发布实体

import javax.persistence.*;
import java.util.List;

@Entity
public class Post 

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    private String title;

    @OneToMany(mappedBy = "post", targetEntity = PostComments.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private List<PostComments> postCommentsList;

  //Getter & Setter

发表评论

import javax.persistence.*;

@Entity
public class PostComments 

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @ManyToOne
    @JoinColumn(name = "post_id", nullable = false)
    private Post post;

    private String review;

    //Getter & Setter

服务

@Stateless
public class PostService 

    @PersistenceContext(unitName = "movie-unit", type = PersistenceContextType.TRANSACTION)
    private EntityManager em;


    public void addPost() 
        PostComments postComments = new PostComments();
        postComments.setReview("Success Review");

        Post post = new Post();
        post.setTitle(" Welcome");
        postComments.setPost(post);
        List<PostComments> postCommentsList = new ArrayList<>();
        postCommentsList.add(postComments);
        post.setPostCommentsList(postCommentsList);

        em.persist(post);

        System.out.println(" Post has been saved .........");
    

    public List<Post> getPost() 
        System.out.println("###########"+em);
        int id = 1;
        Post post = em.find(Post.class, id);
        return Arrays.asList(post);
        //return em.createQuery("select e from Post as e").getResultList();
    



后测

public class PostTest extends TestCase 

    @EJB
    private PostService postService;

    protected void setUp() throws Exception 
        final Map p = new Properties();
        p.put("movieDatabase", "new://Resource?type=DataSource");
        p.put("movieDatabase.JdbcDriver", "org.hsqldb.jdbcDriver");
        p.put("movieDatabase.JdbcUrl", "jdbc:hsqldb:mem:moviedb");
        EJBContainer.createEJBContainer(p).getContext().bind("inject", this);
    

    @Test
    public void testPost() 
        postService.addPost();
        List<Post> postList = postService.getPost();
        System.out.println(" postList = "+postList);
        assertEquals(1,postList.size());
        System.out.println(postList.get(0).getTitle()+" "+postList.get(0).getPostCommentsList().get(0).getReview());
    




JPA 查询

INSERT INTO Post (id, title) VALUES (?, ?) [params=(int) 1, (String) 欢迎]

PostComments (id, review, post_id) VALUES (?, ?, ?) [params=(int) 51, (String) Success Review, (int) 1]

从帖子 t0 左侧选择 t0.title、t1.post_id、t1.id、t1.review OUTER JOIN PostComments t1 ON t0.id = t1.post_id WHERE t0.id = ? ORDER BY t1.post_id ASC [params=(int) 1]

例外

严重 - EjbTransactionUtil.handleSystemException: null org.apache.openjpa.persistence.PersistenceException:空 FailedObject:1 [org.apache.openjpa.util.IntId] [java.lang.String] 在 org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:1029) 在 org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:923) 在 org.apache.openjpa.kernel.DelegatingBroker.find(DelegatingBroker.java:230) 在 org.apache.openjpa.persistence.EntityManagerImpl.find(EntityManagerImpl.java:495) 在 org.apache.openejb.persistence.JtaEntityManager.find(JtaEntityManager.java:224) 在 com.demo.ex.service.PostService.getPost(PostService.java:41) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:498) 在 org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:205) 在 org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:186) 在 org.apache.openejb.monitoring.StatsInterceptor.record(StatsInterceptor.java:191) 在 org.apache.openejb.monitoring.StatsInterceptor.invoke(StatsInterceptor.java:102) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:498) 在 org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:205) 在 org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:186) 在 org.apache.openejb.core.interceptor.InterceptorStack.invoke(InterceptorStack.java:85) 在 org.apache.openejb.core.stateless.StatelessContainer._invoke(StatelessContainer.java:252) 在 org.apache.openejb.core.stateless.StatelessContainer.invoke(StatelessContainer.java:212) 在 org.apache.openejb.core.ivm.EjbObjectProxyHandler.synchronizedBusinessMethod(EjbObjectProxyHandler.java:265) 在 org.apache.openejb.core.ivm.EjbObjectProxyHandler.businessMethod(EjbObjectProxyHandler.java:260) 在 org.apache.openejb.core.ivm.EjbObjectProxyHandler._invoke(EjbObjectProxyHandler.java:89) 在 org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:347) 在 com.demo.ex.service.PostService$$LocalBeanProxy.getPost(com/demo/ex/service/PostService.java) 在 com.demo.ex.PostTest.testPost(PostTest.java:30) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:498) 在 junit.framework.TestCase.runTest(TestCase.java:176) 在 junit.framework.TestCase.runBare(TestCase.java:141) 在 junit.framework.TestResult$1.protect(TestResult.java:122) 在 junit.framework.TestResult.runProtected(TestResult.java:142) 在 junit.framework.TestResult.run(TestResult.java:125) 在 junit.framework.TestCase.run(TestCase.java:129) 在 junit.framework.TestSuite.runTest(TestSuite.java:252) 在 junit.framework.TestSuite.run(TestSuite.java:247) 在 org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86) 在 org.junit.runner.JUnitCore.run(JUnitCore.java:137) 在 com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) 在 com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47) 在 com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) 在 com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) 引起:java.lang.NullPointerException at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.setInverseRelation(JDBCStoreManager.java:452) 在 org.apache.openjpa.jdbc.kernel.JDBCStoreManager.initializeState(JDBCStoreManager.java:412) 在 org.apache.openjpa.jdbc.kernel.JDBCStoreManager.initialize(JDBCStoreManager.java:305) 在 org.apache.openjpa.kernel.DelegatingStoreManager.initialize(DelegatingStoreManager.java:112) 在 org.apache.openjpa.kernel.ROPStoreManager.initialize(ROPStoreManager.java:57) 在 org.apache.openjpa.kernel.BrokerImpl.initialize(BrokerImpl.java:1048) 在 org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:1006) ... 46 更多

javax.ejb.EJBException: bean 遇到非应用程序 例外;嵌套异常是: org.apache.openjpa.persistence.PersistenceException:空 FailedObject: 1 [org.apache.openjpa.util.IntId] [java.lang.String]

在 org.apache.openejb.core.ivm.BaseEjbProxyHandler.convertException(BaseEjbProxyHandler.java:447) 在 org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:351) 在 com.demo.ex.service.PostService$$LocalBeanProxy.getPost(com/demo/ex/service/PostService.java)

依赖关系

<dependency>
    <groupId>org.apache.tomee</groupId>
    <artifactId>javaee-api</artifactId>
    <version>8.0</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.apache.tomee</groupId>
    <artifactId>openejb-core</artifactId>
    <version>8.0.0-M1</version>
    <scope>test</scope>
</dependency>

【问题讨论】:

你确定Post id = 1?可能是另一个值 是的,帖子 ID = 1。 SELECT t0.title, t1.post_id, t1.id, t1.review FROM Post t0 LEFT OUTER JOIN PostComments t1 ON t0.id = t1.post_id WHERE t0.id = ? ORDER BY t1.post_id ASC [params=(int) 1] 我的意思是在数据库中而不是在查询中 是的,INSERT INTO Post (id, title) VALUES (?, ?) [params=(int) 1, (String) Welcome] PostComments (id, review, post_id) VALUES (?, ? , ?) [params=(int) 51, (String) Success Review, (int) 1] 你试过this吗? 【参考方案1】:

您似乎在运行代码之前没有增强实体,因此某些功能无法完全发挥作用:http://openjpa.apache.org/enhancement-with-maven.html

或者你可以在测试JVM上设置openejb-javaagent(通过surefire args你可以像http://tomee.apache.org/javaagent.html一样传递-javaagent:/path/to/openejb-javaagent.jar),它会做同样的事情(字节码检测)但是在运行时就像在普通的 tomee 中一样

附注:如果您不需要跨多个提供程序移植此代码,建议您增强构建时间

罗曼

【讨论】:

【参考方案2】:

我刚刚尝试了与 Hibernate 提供程序相同的代码。它运行良好。相同的代码不适用于 Open JPA :(

Persistence.xml

<provider>org.hibernate.ejb.HibernatePersistence</provider>

依赖关系

<dependency>
    <groupId>org.apache.tomee</groupId>
    <artifactId>openejb-core-hibernate</artifactId>
    <version>8.0.0-SNAPSHOT</version>
    <type>pom</type>
    <scope>test</scope>
</dependency>

【讨论】:

这不是答案。这是添加到您的问题的额外信息

以上是关于JPA,打开 JPA OneToMany - FailedObject的主要内容,如果未能解决你的问题,请参考以下文章

不加入子表的 JPA (@OneToMany) 查询

JPA、OneToMany 和 ManyToOne

JPA @OneToMany 不保存父 ID

JPA - OneToMany 坚持 - EntityExistsException

JPA:关于 OneToMany 关系中阻抗不匹配的问题

为啥在看到 PersistentBag 的实体中使用 JPA 列出(@OneToMany)