2016-09-29 82 views
0

我有两个实体的作用和格兰特与下面的映射:插入新的实体产生级联坚持,而不是级联合并

public class Role extends BaseBean { 
    private static final long   serialVersionUID = 1L; 
    private String      name; 
    private Set<Grant> grants = new HashSet<Grant>(); 
// get set 
} 

public class Grant implements Serializable { 
    private static final long serialVersionUID = 1L; 
    private String   id; 
    private String   data; 
} 

映射ORM:

<entity name="q2role" class="tn.waycon.alquasar2.adm.model.Role"> 
     <attributes> 
      <basic name="name"> 
       <column length="800" nullable="false" unique="true"/> 
      </basic> 
      <many-to-many name="grants" fetch="EAGER"> 
       <join-table name="role_grant"> 
        <join-column name="role_id"/> 
        <inverse-join-column name="grant_id"/> 
       </join-table> 
       <cascade> 
        <cascade-all/> 
       </cascade> 
      </many-to-many> 
     </attributes> 
    </entity> 

<entity name="q2grant" class="tn.waycon.alquasar2.adm.model.Grant"> 
     <attributes> 
      <id name="id"> 
       <column name="id_g"/> 
       <generated-value stategy="IDENTITY" generator="SEQ_GEN"/> 
      </id> 
      <basic name="data"></basic> 
     </attributes> 
</entity> 

现在,当我尝试插入包含现有授权的新角色时,事务将失败,因为eclipselink正在尝试插入已存在的授予。为什么eclipselink正在做这种奇怪的行为?我正在设置cascade-all,eclipselink必须足够聪明才能在cascade-persist和cascade-merge之间分离。

Main { 
Role role = new Role(); 
List<Grant> grants = grantRepository.getGrantsBydata(List<String> datas); 
role.setGrants(grants); 
roleRepository.save(role); 
} 

日志:

警告[HTTP-NIO-8080-EXEC-2] org.springframework.remoting.support.RemoteInvocationTraceInterceptor.invoke 处理HttpInvokerServiceExporter远程呼叫导致致命 异常tn.waycon.alquasar2.adm.service.api.IAdminService.createRole org.springframework.transaction.TransactionSystemException:可能 未提交事务JPA;嵌套异常是 javax.persistence.RollbackException:异常[EclipseLink-4002] (Eclipse持久性服务 - 2.5.2.v20140319-9ad6abd) org.eclipse.persistence.exceptions.DatabaseException内部 异常:java.sql.BatchUpdateException:违反PRIMARY KEY “PK__Q2GRANT__9DB7D2FA15DA3E5D”。不能插入 对象“dbo.Q2GRANT”重复键重复的键值(13969)错误代码:。2627

+0

您的保存方法是使用合并还是持续? – Chris

+0

我正在使用spring数据jpa,JpaRepository接口中只有一个保存方法,具体取决于主键是否为null,它将决定使用合并还是持久化。 –

回答

1

调用持续性会导致JPA插入根实体,但它也会级联持续调用跨标记为级联人的关系ist类型。这间接意味着你正在调用持久化在你的分离的实体上,JPA规范要求提供者立即或当事务与数据库同步(插入语句)时引发异常。

持续和级联持久性选项仅用于在要插入新对象图时使用,因此您可能需要重新评估放置在级联持久性选项中的位置 - 它具有后果。

选项是

  1. 阅读在现有实体将它们添加到新的实体 和使用管理的实例之前。因为坚持托管实体 是无效的,这将解决您的问题。
  2. 改为使用合并。合并 允许提供者查看实体实例,以确定它是否是新的或更新,并且如指定的那样级联到图。 然后合并将把你的分离的实体并通过更新它适当地处理它 。
0

补助金是由角色分别管理,应该删除 使用指当一个角色。插入,所有的授权也会被插入,当它被删除时,授权也会被删除 在你的情况下,我可以看到授权在创建角色时已经存在,所以你不希望它们被删除当角色将被删除时!