当我使用 Arquillan 运行我的集成测试时,我收到以下错误消息javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist
。这可能与我的 ID 和数据库有关。
以下是它抱怨它的域类的类:
@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;
}
}
我还有一个 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;
}
}
最后我得到了我正在使用 arquillan 的集成测试。当我运行测试时,上面的错误出现了: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();
}
}
和
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);
}
}
当我无法解决这个问题时,我真的觉得自己像个白痴,谁能帮助我并解释什么是错的?