1

상위 개체에서만 포함 된 고유 한 자식 개체로 엔티티 (부모)를 저장/유지하고 싶습니다. 중복 아이가 나타날 때까지 뭐든지 여기에 내가 예외 다음 얻을, 잘 작동 : 처음에는최대 절전 모드 : 이미 존재하는 자식 (단방향)으로 부모 개체 저장

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 


당신은 내가 아이가 이미 있는지 확인하는 식 session.bySimpleNaturalId(Child.class).load(child.getMd5Hash())를 사용하고 있음을 알고있다, 왜냐하면 모든 자식 개체는 명시 적으로 기본 키로 할당되지 않은 고유 해시 값 (초기화 후 생성됨)을 가지기 때문입니다 (기본 키는 자동 증가, strategy = GenerationType.TABLE).

내 DAO에서 session.merge(child) 또는 다른 표현식을 사용하는지 여부에 관계없이 동일한 예외가 발생합니다.

내 부모 - 대상 :

@Entity 
@Table(name = "parent") 
public class Parent implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.TABLE) 
    private Long id = null; 


    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) 
    @JoinColumn(name = "kind_child_id", referencedColumnName = "md5hash") 
    private Child firstChild; 

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) 
    @JoinColumn(name = "rude_child_id", referencedColumnName = "md5hash") 
    private Child secondChild; 

    //private String attributes; 
    //Getters & Setters 

내 아동 대상 :

public void writeParent(Parent parent) { 
       try { 
        if (parent != null) { 
         if (globalSession == null) { 
          globalSession = getSessionFactory().openSession(); 
         } 
         globalSession.beginTransaction(); 

          if (parent.getFirstChild() != null) { 
           Child tempFirstChild = (Child) globalSession.bySimpleNaturalId(Child.class).load(parent.getFirstChild().getMd5Hash()); 
           if (tempFirstChild != null) { 
            parent.setFirstChild(tempFirstChild); 
            //globalSession.merge(tempFirstChild); 
            //throws MySQLICV-Exception 

            //globalSession.update(tempFirstChild); 
            //throws MySQLICV-Exception 
           } 
          } 
          if (parent.getSecondChild() != null) { 
           Child tempSecondChild = (Child) globalSession.bySimpleNaturalId(Child.class).load(parent.getSecondChild().getMd5Hash()); 
           if (tempSecondChild != null) { 
            parent.setSecondChild(tempSecondChild); 

            //globalSession.merge(tempSecondChild); 
            //throws MySQLICV-Exception 

            //globalSession.update(tempSecondChild); 
            //throws MySQLICV-Exception 

           } 
          } 

         globalSession.saveOrUpdate(parent); 
         //globalSession.persist(parent); 
         globalSession.getTransaction().commit(); 
        } 
       } catch (Exception ex) { 
        log.error("FAILURE: ", ex); 
       } 
finally{ 
globalSession.close(); 
} 
      } 
: 여기

@Entity 
@Table(name = "child") 
public class Child implements Serializable { 

     @Id 
     @GeneratedValue(strategy = GenerationType.TABLE) 
     private Long id = null; 

     @NaturalId 
     @Column(name="md5hash", unique=true) 
     private char[] md5hash = new char[32]; 

     //private String attributes; 
     //Getters & Setters 


그리고이 (검증 포함) 부모를 지속/저장하는 나의 방법이다


메이브 e 나는 다큐멘터리 전체를 이해하지 못했기 때문에 이것을 생각해 냈습니다 : 심지어 Hibernate에게 발견 된 엔티티들을 합쳐야한다고 말할 필요가 있습니까? Hibernate에게 그 자식들을 영속화 될 필요가있는 새로운 객체로 다루어서는 안된다고 어떻게 말할 수 있습니까? 양방향 관계로 전환해야합니까? (현재이 경우 양방향 관계를 사용할 수 없습니다.)

모든 힌트는 대단히 감사 드리며 미리 감사드립니다. 감사합니다, 예티

+0

처음에 당신을있는 업데이트하거나 자식 객체를 저장하려고 왜 나를 이해하자, 상위 가진 사람들을 연결하고 당신이 부모를 업데이트/저장하는, 그들은 어쨌든 것 지속 되었습니까? – zerocool

+0

@zerocool 물론 그들은 어쨌든 유지 될 것이고, 당신이 참조하는 메소드는 테스트 작업만을위한 것이며, 아이의 일부 속성을 수정하려고 할 수도 있습니다. – Yeti

답변

0

대답 a.k.a 실수를 직접 발견했습니다. 처음에는 문제를 해결하기 위해 별도의 함수를 사용하여 자식이 있는지 확인하고 별도의 세션을 사용하여 확인했습니다 (L2C가 비활성화되어 있으면 작동하지 않을 수도 있음).

synchronized public Child checkChild(Child child) { 
    try { 
     if (child != null) { 
      tempSession = getSessionFactory().openSession(); 
      Child tempChild = (Child) tempSession.bySimpleNaturalId(Child.class).load(Child.getMd5Hash()); 
      if (tempChild != null) { 
       return tempChild; 
      } else { 
       return child; 
      } 
     } else { 
      return null; 
     } 
    } catch (Exception ex) { 
     return null; 
    } 
    finally{ 
     tempSession.close(); 
    } 
} 
초에서

와 단서가있다, 나는 그래서 그냥 방법에서 새로운 부모 개체를 시작하고 끝낼 잘못이다 parametrical 값으로 부모 개체를 저장하려고. 잘

public void writeParent(Parent parent) { 
    tempParent = new Parent(); 
    tempParent.setFirstChild(checkChild(tempParent.getFirstChild())); 
    tempParent.setSecondChild(checkChild(tempParent.getSecondChild())); 
    globalSession = getSessionFactory().openSession(); 
    globalSession.beginTransaction(); 
    globalSession.saveOrUpdate(tempParent); 
    globalSession.getTransaction().commit(); 
    globalSession.close(); 
}