2009-12-15 5 views
0

:최대 절전 모드 폭포가 작동하지 삭제할이 내 부모이며, 내 아이가 개체를 가정하면

부모 :

@Entity 
@Table(name = "import_table") 
public class ImportTable { 
    @Cascade({ CascadeType.ALL, CascadeType.DELETE_ORPHAN }) 
    @OneToMany(
     mappedBy = "table", 
     fetch = FetchType.EAGER 
    ) 
    public List<ImportTableColumn> getColumns() 
    { 
     return columns; 
    } 
    ... setter is defined but I don't think it's important for the example 
} 

아이 :

@Entity 
@Table(name = "import_table_column") 
public class ImportTableColumn { 
    @ManyToOne 
    @JoinColumn(
     name = "import_table_name", 
     nullable = false 
    ) 
    public ImportTable getTable() 
    { 
     return table; 
    } 
} 

다음의 의사 코드는 작동합니다

  • ImportTable의 인스턴스를 만들고 2 개의 열을 추가하고 세션을 만들고 저장하고 세션을 닫습니다.
  • 저장된 세션을 다른 세션에서 읽고 한 열을 제거하십시오.
  • 다른 세션에서 저장하십시오.
  • 열 수를 확인하고 1과 같습니다.

하지만 다음은 작동하지 않습니다

  • ImportTable의 인스턴스를 생성, 세션을 닫고, 저장, 2 열을 추가 세션을 생성;
  • 저장된 세션을 다른 세션에서 읽습니다.
  • 저장된 개체를 수동으로 다시 만듭니다.
  • 열을 제거하십시오.
  • 다른 세션에서 저장하십시오.
  • 열 수를 확인하고 1과 같습니다.

우리가 Java 서버/Flex 클라이언트 응용 프로그램을 가지고 있기 때문에 우리는 개체를로드하고 클라이언트에게 보내야하며 클라이언트가해야 할 일은 무엇이든 할 수있게해야합니다. 서버에 저장 한 다음 저장하십시오.

개체를 다시 만들 때 Hibernate가 손실된다고 생각합니다. 내가 아는 한, Hibernate는 데이터베이스에서 객체를 가져올 때 객체에 무엇인가를 주입한다. 개체를 다시 만들 때 개체 클래스에 선언 된 필드가 아닌 것은 복사하지 않습니다.

private ImportTable recreate(ImportTable original) throws IOException 
{ 
    final ImportTable copy = new ImportTable(); 
    copy.setDatabaseTableName(original.getDatabaseTableName()); 
    copy.setDisplayTableName(original.getDisplayTableName()); 
    if(original.getColumns() != null) { 
     copy.setColumns(new ArrayList<ImportTableColumn>(original.getColumns().size())); 
     for(ImportTableColumn originalColumn : original.getColumns()) { 
      final ImportTableColumn copyColumn = new ImportTableColumn(); 
      copyColumn.setTable(copy); 
      copyColumn.setDatabaseColumnName(originalColumn.getDatabaseColumnName()); 
      copyColumn.setDatatype(originalColumn.getDatatype()); 
      copyColumn.setExcelColumnName(originalColumn.getExcelColumnName()); 
      copyColumn.setId(originalColumn.getId()); 
      copyColumn.setLength(originalColumn.getLength()); 
      copyColumn.setPk(originalColumn.isPk()); 
      copyColumn.setRequired(originalColumn.isRequired()); 
      copyColumn.setPrecision(originalColumn.getPrecision()); 
      copy.getColumns().add(copyColumn); 
     } 
    } 
    return copy; 
} 

내가 개체를 다시 만들 때 손실지고 최대 절전 모드 생각 :이 (내 단위 테스트에 대한) 오브젝트를 재 작성하는 코드이다. 절전 모드에서 데이터베이스에있는 내용과 오브젝트에있는 내용을 비교하여 차이점 만 저장하면됩니다. 그것을 할 방법이 있습니까?

답변

2

Hibernate는 소유자 엔티티가 세션에 처음 첨부 될 때 AbstractPersistentCollection의 적절한 서브 클래스에 콜렉션 인스턴스를 랩핑한다.

그런 다음 PersistentCollection은 삭제 된 수집 요소를 추적합니다. Hibernate가 없으면 Hibernate는 그것들에 삽입/갱신을 수행 할 수있을 것이다 (대부분의 경우, 어떤 id generator 클래스에 대해서조차 불가능하다).

당신은 기본적으로 운이 없다. 데이터베이스에서 기존 엔티티 (ImportTable)를로드하고 수정해야합니다.로드 된 사본에는 있지만 콜론에는없는 콜렉션 요소를 삭제하십시오.) 그런 다음 저장하십시오.

그렇다면 필자가 처음 엔 엔티티를 복제해야하는 이유가 무엇인지 잘 모르겠다. (필자는 플렉스에 대해 모르지만 XML/JSON/등으로 엔티티를 마샬링하고 있는가?) 모든 PersistentCollection 구현 Serializable이고 따라서 전선과 뒷면으로 보낼 수 있습니다. XML을 마샬링하고 다시 사용할 수있는 방법이 있습니다.

+0

플렉스 엔진 (flex.messaging)은 개체를 serialize하지 않으며, 엔진이 리플렉션을 사용하여 필드를 읽은 다음 flex 클라이언트와 호환되는 자체 직렬화 엔진을 사용한다고 생각합니다. 난 그냥 소스 코드를 확인했다, 목록이 클라이언트에서 돌아올 때, 엔진은 내용을 보유 ArrayList를 만듭니다. 나는 해결책을 직접 구현해야 할 것 같다. 나는 리플렉션 (commons-bean을 통해)을 사용하여 모든 객체 getter를 읽고, 목록이 있는지 파악한 다음 데이터베이스를 읽고 거기에있는 최대 절전 모드 주석을 사용하여 목록 ID를 비교할 수 있습니다. –

+0

@Id 주석을 읽음으로써. 그 케이스가 여분의 코딩을 정당화 할만큼 자주 발생하는지 평가할 것입니다. 그렇지 않으면 객체 자체에서 수동으로 할 수 있습니다. –