java - 为什么我的代码没有抛出 EntityExistsException

标签 java mysql jakarta-ee exception jpa

我目前正在研究 Java EE 7,并试图弄清楚何时会引发 EntityExistsException。我目前有一个非常简单的具有基本属性的 Message 类。据我理解,当数据库中已经存在要持久化的具有相同主键的实体时,应该抛出 EntityExistsException 。我不太确定该实体是否分离是否重要,因此进行了快速测试,看看它何时会发生。然而,这两个测试用例由于某种原因都通过了,但没有向我显示错误。

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import org.iys.jpa.mysql.example.Message;
import org.junit.After;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;

public class MessageIT {

    private static EntityManagerFactory emf ; 
    private EntityManager em;
    private EntityTransaction tx;

    public MessageIT() {
    }

    @Before
    public void setUp() {
       emf= Persistence.createEntityManagerFactory("JPAMYSQLExampleU");
        em = emf.createEntityManager();
        tx = em.getTransaction();
        Message m1= new Message("Hello");       
        tx.begin();
        em.persist(m1);        
        tx.commit();
        System.out.println("Setting up the test");
    }

    @After
    public void tearDown() {
        if (em != null) {
            em.close();
        }
    }

    //either one of the test should fail

    @Test
    public void shouldFail1(){
        Message msg = em.find(Message.class, 1L);
        Message copied= msg;    
        copied.setMessage("changed");
        assertTrue(em.contains(msg));
        em.clear();
        assertFalse(em.contains(msg));
        assertFalse(em.contains(copied));  //both entities are currently detached
        tx.begin();
       em.persist(copied);

        tx.commit();

    }
    @Test
    public void shouldFail2(){
        Message msg = em.find(Message.class, 1L);
        assertTrue(em.contains(msg));
        tx.begin();
        em.persist(msg);
        tx.commit();
    }
}

如果我误解了错误发生的条件,您将如何更改代码以便引发上述错误。

最佳答案

您可能正在使用 @GenerateValue 作为您的 ID(如果您可以在问题中提供实体实现,那就太好了)。在这种情况下,具有持久性的提供者可能只是在持久化实体之前生成新的 id。 (这就是为什么shouldFail1不会失败)。

如果 shouldFail2 规范指出:

If X is a preexisting managed entity, it is ignored by the persist operation.

由于您的 msg 是在该测试中管理的,因此将忽略 persist。

您最好切换到提供的 Id,而不是生成的 Id 来测试 EntityExistsException 情况。

关于java - 为什么我的代码没有抛出 EntityExistsException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25612096/

相关文章:

java - 在 Java 中计算可用内存的最佳方法是什么?

java - 如何通过在 glassfish 中部署的应用程序定义不同的连接池

mysql - 构建MySQL通过多个同值标识确定 "length of lifecycle"

java - Java EE项目的静态代码分析工具

java - Apache Tomcat 是Web服务器还是应用服务器

java - 为什么不调用实现 Runnable 接口(interface)的类的构造函数?

Java 测验 - 正确时不接受用户输入

mysql - 从 PHP 将日期存储在 MySQL 中的最佳实践

mysql - 在 Perl 中跟踪不确定的 MySQL 错误

web-services - 如何将 Apache CXF Web 服务部署到 Glassfish