简体   繁体   English

EJB3映射分离实体已传递以持久化

[英]EJB3 Mapping detached entity passed to persist

When I run my Integrationtesting with Arquillan I get the following Error meesage javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist . 当我使用Arquillan运行Integrationtesting时,出现以下错误消息javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist Which probably is something with my ID and database. 这可能与我的ID和数据库有关。

Following is the class it is complaining about its a domain class : 以下是它抱怨其域类的类:

@Entity
public class Customer implements IdHolder {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    private String firstName;
    private String lastName;
    private String email;
    private String company;

    public Customer() {

    }


    public Customer(long id, String firstName, String lastName, String email,
            String company) {
        setId(id);
        setFirstName(firstName);
        setLastName(lastName);
        setEmail(email);
        setCompany(company);

    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getCompany() {
        return company;
    }

    public void setCompany(String company) {
        this.company = company;
    }

}

I have also have a testfixture to make test easier and its implemented like this : 我也有一个testfixture可以简化测试,它的实现方式如下:

public class TestFixture {

    private static Logger log = Logger.getLogger(TestFixture.class.getName());

    public static Customer getCustomer(long id, String firstName,
            String lastName, String email, String company) {

        Customer customer = new Customer();
        customer.setId(id);
        customer.setFirstName(firstName);
        customer.setLastName(lastName);
        customer.setEmail(email);
        customer.setCompany(company);

        return customer;

    }

    public static Customer getCustomer() {

        return getCustomer(1, "Darth", "Vader", "skywalker@gmail.com", "Starwars");

    }

    public static Customer getCustomer(String name, String lastName, String email, String company) {

        return getCustomer(0, name, lastName, email, company);

    }

    public static Archive<?> createIntegrationTestArchive() {

        MavenDependencyResolver mvnResolver = DependencyResolvers.use(
                MavenDependencyResolver.class).loadMetadataFromPom("pom.xml");

        WebArchive war = ShrinkWrap.create(WebArchive.class, "agent_test.war")
                .addPackages(true, "se.lowdin")
                .addPackages(true, "se.plushogskolan")
                .addAsWebInfResource("beans.xml")
                .addAsResource("META-INF/persistence.xml");

        war.addAsLibraries(mvnResolver.artifact("org.easymock:easymock:3.2")
                .resolveAsFiles());
        war.addAsLibraries(mvnResolver.artifact("joda-time:joda-time:2.2")
                .resolveAsFiles());
        war.addAsLibraries(mvnResolver.artifact(
                "org.jadira.usertype:usertype.core:3.1.0.CR8").resolveAsFiles());

        log.info("JAR: " + war.toString(true));
        return war;
    }

}

And finally I have the integration test that I am using arquillan with. 最后,我进行了与Arquillan一起使用的集成测试。 When I run the test the error above is coming up : javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist 当我运行测试时,上面的错误将出现: javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist

@RunWith(Arquillian.class)
@Transactional(TransactionMode.ROLLBACK)
public class JpaCustomerIntegrationTest extends AbstractRepositoryTest<Customer, JpaCustomerRepository> {

    @Inject JpaCustomerRepository repo;

    @Test
    public void testGetAllCustomers() {

        Customer customer1 = TestFixture.getCustomer();
        Customer customer2 = TestFixture.getCustomer();
        customer1.setId(0);
        customer2.setId(0);
        repo.persist(customer1);
        repo.persist(customer2);

        List<Customer> getAllCustomersList = repo.getAllCustomers();
        assertEquals("Check the amount from the list", 2, getAllCustomersList.size());

    }

    @Override
    protected JpaCustomerRepository getRepository() {

        return (JpaCustomerRepository) repo;
    }

    @Override
    protected Customer getEntity1() {

        return TestFixture.getCustomer();
    }

    @Override
    protected Customer getEntity2() {

        return TestFixture.getCustomer();
    }

}

and

public abstract class JpaRepository<E extends IdHolder> implements BaseRepository<E> {

    /**
     * The JPA type this repository can handle. Only known at runtime. This
     * value is set in the constructor.
     */
    protected Class<E> entityClass;

    @PersistenceContext
    protected EntityManager em;

    @SuppressWarnings("unchecked")
    public JpaRepository() {
        /*
         * A little magic to look into the superclass to find the type we are
         * working on. We use that type in findById() for example .
         */
        ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
        this.entityClass = (Class<E>) genericSuperclass.getActualTypeArguments()[0];
    }

    @Override
    public long persist(E entity) {
        em.persist(entity);
        return entity.getId();
    }

    @Override
    public void remove(E entity) {
        em.remove(entity);
    }

    @Override
    public E findById(long id) {
        return em.find(entityClass, id);
    }

    @Override
    public void update(E entity) {
        em.merge(entity);
    }

}

I really feel like an idiot when I am not able to solve this can anyone help me and explain what is wrong? 当我无法解决此问题时,我真的像个白痴,谁能帮助我并解释出什么问题了?

You could change Customer.id from long to Long . 您可以将Customer.idlong更改为Long Before persisting the entity just set Id to null . 在保留实体之前,只需将Id设置为null This should help. 这应该有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM