2010-02-08 2 views
1

У меня есть родительское (программное) pojo с отношениями «многие ко многим» со своими детьми (подписчик).Циклическая сериализация со многими для многих отношений с Hibernate

Проблема заключается в том, когда она сериализует программу, она также сериализует подписчиков программы, которая включает сериализацию своих программ, которая включает сериализацию своих подписчиков, до тех пор, пока она не сериализует каждую отдельную программу & Абонент в базе данных.

ERD выглядит следующим образом: Программа < -> Абонент

Это означает, что было крошечным 17Kb блок данных (JSON) возвращаются стало возвращением 6.9MB. Таким образом, в свою очередь, выдувает время для сериализации данных и затем возвращает их.

Почему мой родитель возвращается детям, возвращающимся родителям, возвращающимся? Как я могу остановить это, поэтому я получаю подписчиков только для каждой программы? Я полагаю, что я сделал что-то не так с моими аннотациями, может быть? Я хотел бы поддерживать отношения «многие ко многим», но без этого глубоко вложенного поиска данных.

(Примечание..? Я до пытался добавить столько Ленивые аннотации я могу найти только увидеть, если это помогает Это не Может быть, я делаю что тоже неправильно)

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

Оба Божо и понкин находятся на правильном пути. Мне нужно было прекратить сериализацию данных по кабелю, но большая проблема заключается в том, что я не могу изменить класс pojo -> toJSON/метод, где происходит сериализация. Я также беспокоился о том, чтобы инвестировать время в метод toJSON(), учитывая, что я принимал такой удар производительности в точке сериализации. Мне нужно исправление, которое произойдет до того, как я буду иметь данные, а не потом.

Также из-за характера двунаправленного дизайна «Множество ко многим», который я перечислил, у меня всегда были проблемы с циклическими программами/подписчиками/программами ....

Разрешение: (сейчас по крайней мере) Я удалил метод Subscriber.getProgram() и создал метод finder в ProgramDAO, который возвращает программы подписчиками.

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; 
} 

Для любого CRUD работы, я думаю, я просто придется перебрать Programs.getSubscribers или написать больше вспомогательных методов HQL.

3

Вы не упомянули структуру, которую вы используете для JSON сериализации, так что я буду считать JAXB. Во всяком случае, идея состоит в том, чтобы сделать Subscriber.getPrograms(..) переходным процессом каким-то образом, чтобы он не был сериализован. Hibernate позаботится об этих «петлях», но другие нет. Таким образом:

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

Если вы используете другой фреймворк, он может иметь другую аннотацию/конфигурацию для указания полей переходных процессов. Как ключевое слово transient.

Другой способ заключается в настройке вашего картографа для обработки цикла вручную, но это утомительно.

+0

Это мой проект, я не на 100%, что используется для сериализации JSON. Я вижу ссылки на com.sdicons.json.mapper.JSONMapper.SimpleMapperHelper. И у нас есть метод public JSONValue toJSON (Object pojo) выдает MapperException {}. (предположим, что это сворачивает вашу собственную сериализацию) –

+0

Также, если я аннотирую getPrograms() @XmlTransient, это означало бы, что я никогда не смог бы вернуть абонентские программы? –

+0

есть. Другой - это настроить ваш картограф, чтобы позаботиться о цикле вручную. – Bozho

1

1) Как работает «ваша» сериализация. Я имею в виду JAXB или пользовательскую сериализацию или smth else. 2) Почти все рамки позволяют установить глубину сериализации. Я имею в виду, что вы можете установить, например, глубину в 2. 3) Я советую вам не сериализовать объект с детьми, пометить их (childre) переходный процесс и сериализовать отдельно.

Смежные вопросы