在Eclipse链接中我遇到了这样的错误:

Caused by: java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: pl.salonea.entities.Education@9a07c360

同时在数据库中保持@ManyToMany关系 .

// wire up both Employee and Education entities
            employee1.getEducations().add(santaClaraUniversity);
            employee1.getEducations().add(stanfordUniversity);
            employee2.getEducations().add(massachusettsInstituteOfTechnology);
            employee3.getEducations().add(massachusettsInstituteOfTechnology);

            santaClaraUniversity.getEducatedEmployees().add(employee1);
            stanfordUniversity.getEducatedEmployees().add(employee1);
            massachusettsInstituteOfTechnology.getEducatedEmployees().add(employee2);
            massachusettsInstituteOfTechnology.getEducatedEmployees().add(employee3);

            // persist employees and educations in database
            employeeFacade.create(employee1);
            employeeFacade.create(employee2);
            employeeFacade.create(employee3);

            educationFacade.create(stanfordUniversity);
            educationFacade.create(santaClaraUniversity);
            educationFacade.create(massachusettsInstituteOfTechnology);

错误在 employeeFacade.create(employee1); 的第一行引发

这段代码在Hibernate和EclipseLink中运行得非常好,存在这样的问题 . 我尝试添加CascadeType.PERSIST但不知道为什么在Hibernate中它可以工作,为什么在EclipseLink中却没有 .

我有点困惑如何坚持@OneToMany,@ManyToOne关系正常?我应该始终设置关系的双方,然后在两边坚持实体吗?我应该在单独的事务中坚持这样,还是应该将它包装在UserTransaction中? (因为这是JTA Arquillian)

UPDATE 1 在双方上面添加CascadeTyp.PERSIST以上代码抛出此类错误

Caused by: javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'Bachelor of Computer Science-Stanford University' for key 'UNQ_education_0'
Error Code: 1062

在线教育.Facade.create(santaClaraUniversity);

UPDATE 2utx.begin()utx.commit() 中的facade.create()代码上面包装之后,似乎是持久化实体,但是删除的另一个问题如下所示

assertTrue(educationFacade.deleteByEmployee(employee1) == 2);

并且此方法实现为:

@Override
public Integer deleteByEmployee(Employee employee) {

    // select educations for given employee that will be deleted in the following query
    List<Education> educations = findByEmployee(employee);

    return deleteByEducations(educations);
}

@Override
public Integer deleteByEducations(List<Education> educations) {

    Query query = getEntityManager().createNamedQuery(Education.DELETE_BY_EDUCATIONS);
    query.setParameter("educations", educations);
    return query.executeUpdate();
}

我已命名查询:

@NamedQuery(name = Education.DELETE_BY_EDUCATIONS, query = "DELETE FROM Education e WHERE e IN :educations")

在休眠中,员工对Educations的批量删除工作正常:

in hibernate it works but in eclipse link not

尽管教育只是反转方面,它甚至在数据库中正确删除了关联......

enter image description here

并且在 EclipseLink 中有0行被删除,我想有一些与约束相关的问题(即多对多关联不能被删除?)教育是关系的反面(使用mappedBy元素)而Employee是拥有方

UPDATE 3 我在deleteByEducations methdod(教育实体)中添加了这样的代码:

for(Education edu : educations) {
        for(Employee empl :edu.getEducatedEmployees()) {
            empl.getEducations().remove(edu);
            getEntityManager().merge(empl);
        }
    }

在连接表的数据库中(对于ManyToMany关系)已删除与此教育相关联的记录(我要删除) . 但教育实体并未持续删除 . 也许上面这个命名查询有什么东西?:

DELETE FROM Education e WHERE e IN :educations

UPDATE 4 实现deleteByEducations()方法这种方式正常工作,因此可能存在命名查询的东西,这样的构造可能与EclipseLink不兼容(但在Hibernate中有效) . 但这种新的解决方案相当麻烦 .

@Override
    public Integer deleteByEducations(List<Education> educations) {

        Integer deletedCount = 0;

        for(Education edu : educations) {
            for(Employee empl :edu.getEducatedEmployees()) {
                empl.getEducations().remove(edu);
                getEntityManager().merge(empl);
            }

            Query query = getEntityManager().createNamedQuery(Education.DELETE_BY_EDUCATION);
            query.setParameter("education", edu);
            deletedCount += query.executeUpdate();
        }

        return deletedCount;
    }

UPDATE 5 此外,此解决方案无需从连接表中删除关联记录也可以正常工作 .

@Override
    public Integer deleteByEducations(List<Education> educations) {

        Integer deletedCount = 0;

        for(Education edu : educations) {

            Query query = getEntityManager().createNamedQuery(Education.DELETE_BY_EDUCATION);
            query.setParameter("education", edu);
            deletedCount += query.executeUpdate();
        }

        return deletedCount;
    }