2010-02-08 4 views
1

나는 그들의 자식 (가입자)과 다 - 대 - 다 관계를 가진 부모 (프로그램) pojo를 가지고있다.Hibernate와의 Many to Many 관계로 순환 직렬화

문제는 프로그램을 serialize 할 때 해당 프로그램의 구독자를 serialize하는 것입니다. 프로그램 구독자는 데이터베이스에 구독자 인 모든 & 구독자를 일련 번호가 매겨 질 때까지 구독자를 serialize하는 과정을 포함합니다. 반환> 가입자

이 데이터 (JSON)의 작은 17킬로바이트 블록을 무슨 의미 6.9MB 반환되었다 - 프로그램 < :

는 ERD는 것 같습니다. 따라서 순차적으로 데이터를 직렬화하고 반환하는 시간을 낭비합니다.

부모님이 자녀를 돌려주는 부모님을 돌려주는 자녀를 돌려주는 이유는 무엇입니까? 어떻게하면 각 프로그램의 구독자 만 얻을 수 있습니까? 내 주석을 잘못 처리했다고 가정하고 있나? 이 many-to-many 관계를 유지하고 싶지만이 중첩 된 데이터 검색이 필요하지 않습니다.

(참고 :..? 내가 전에 난 그냥이 도움이 있는지 확인하기 위해 찾을 수있는 많은 게으른 주석으로 추가하는 시도 그것은 아마도 내가 잘못도 그 일을 해요하지 않습니다)

Program.java

@Entity 
@Table(name="programs") 
public class Program extends Core implements Serializable, Cloneable { 
    ... 
    @ManyToMany() 
    @JoinTable(name="program_subscribers", 
     joinColumns={@JoinColumn(name="program_uid")}, 
     inverseJoinColumns={@JoinColumn(name="subscriber_uid")}) 
    public Set<Subscriber> getSubscribers() { return subscribers; } 
    public void setSubscribers(Set<Subscriber> subscribers) { this.subscribers = subscribers; } 

Subscriber.java

@Entity 
@Table(name="subscribers") 
public class Subscriber extends Core implements Serializable { 
    ... 
    @ManyToMany(mappedBy="subscribers") 
    public Set<Program> getPrograms() { return programs; } 
    public void setPrograms(Set<Program> programs) { this.programs = programs; 

}

구현

public Collection<Program> list() { 
    return new Programs.findAll(); 
} 

답변

-1

Bozho와 ponkin 모두 올바른 경로에 있습니다. 나는 데이터를 직렬화하는 것을 중지해야했지만 큰 문제는 직렬화가 발생하는 pojo -> toSSON 클래스/메소드를 변경할 수 없다는 것입니다. 필자는 serialization 시점에서 성능이 떨어지는 것을 고려하여 toJSON() 메서드에 시간을 투자하는 것에 대해 걱정했습니다. 이후에 데이터가 나오기 전에 발생하는 문제를 원했습니다.

내가 다룬 Many-to-Many 양방향 디자인의 특성 때문에 나는이 순환 프로그램/구독자/프로그램/... 문제를 항상 가질 것입니다.

해상도 : (당분간은) Subscriber.getProgram() 메서드를 제거하고 Subscriber가 프로그램을 반환하는 ProgramDAO에서 finder 메서드를 만들었습니다. 난 그냥 Programs.getSubscribers을 통해 루프, 또는 더 HQL 헬퍼 메소드를 작성하는 것 같네요 어떤 CRUD 작업

public List<Program> findBySubscriber(Subscriber subscriber) { 
    String hql = "select p " + 
    "from Program p " + 
    " join p.subscribers s " + 
    "where s = :sub" 
    ;  

    Query q = getSession().createQuery(hql); 
    q.setEntity("sub", subscriber); 

    List<Program> l = q.list(); 
    return l; 
} 

.

3

당신은 JSON 직렬화에 사용하는 프레임 워크를 언급하지 않았다, 그래서 JAXB를 가정합니다. 어쨌든, 그 아이디어는 어떤 식 으로든 Subscriber.getPrograms(..) transient를 만드는 것이므로 직렬화되지 않습니다. Hibernate는 이러한 '루프'를 처리하지만 다른 것들은 처리하지 않습니다. 따라서 :

@XmlTransient 
@ManyToMany(..) 
public Set<Program> getPrograms()... 

다른 프레임 워크를 사용하는 경우 일시적인 필드를 지정하기 위해 다른 주석/구성이있을 수 있습니다. transient 키워드와 같습니다.

다른 방법은 사이클을 수동으로 처리하도록 매퍼를 사용자 정의하는 것이지만 이것은 지루합니다.

+0

이 프로젝트는 손에 땀을 쥐게합니다. JSON 직렬화에 사용되는 것이 100 % 아닙니다. com.sdicons.json.mapper.JSONMapper.SimpleMapperHelper에 대한 참조가 있습니다. 그리고 우리는 메소드 public JSONValue toJSON (Object pojo)가 MapperException {}을 던졌습니다. (그것은 자신의 직렬화를 추측하는 것입니다) –

+0

또한 getPrograms() @ XmlTransient 주석을 달았다면 구독자 프로그램을 반환 할 수 없었을 것입니다. –

+0

예. 다른 하나는 매퍼를 사용자 정의하여주기를 수동으로 처리하는 것입니다. – Bozho

1

1) "귀하의"직렬화는 어떻게 작동합니까? JAXB 또는 사용자 정의 직렬화 또는 다른 것입니다. 2) 거의 모든 프레임 워크에서 일련 번호를 설정할 수 있습니다. 내 말은 당신이 깊이 2로 설정할 수 있음을 의미합니다. 3) 나는 아이들과 함께 객체를 직렬화하지 말고, 자식 (childre)을 일시적으로 표시하고 따로 직렬화하지 말라고 조언합니다.