Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / JPA2 проблема с связанными коллекциями при отношении Многие-ко-многим / 11 сообщений из 11, страница 1 из 1
17.08.2012, 13:47:00
    #37920787
alex2808
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JPA2 проблема с связанными коллекциями при отношении Многие-ко-многим
Всем привет!
Есть классы TaskEntity, PersonEntity, StatusEntity.
TaskEntity и StatusEntity связанs много-к-одному.
TaskEntity и PersonEntity связаны многие-ко-многим.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
@Entity
@Table(name = "Person")
public class PersonEntity implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String phoneNumber;
    private Long inn;
    private String pass;
    private String fio;
   private Long tabNum;
    private Short type;
    
   @ManyToMany(mappedBy="persons")
    private Collection<TaskEntity> tasks;

    public PersonEntity() {
    }

    public PersonEntity(String phoneNumber, Short type) {
        this.phoneNumber = phoneNumber;
        this.type = type;
    }

   
   public Collection<TaskEntity> getTasks() {
        return tasks;
    }

    public void setTasks(Collection<TaskEntity> tasks) {
        this.tasks = tasks;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    public Long getInn() {
        return inn;
    }

    public void setInn(Long inn) {
        this.inn = inn;
    }

    public String getPass() {
        return pass;
    }

    public void setPass(String pass) {
        this.pass = pass;
    }

    public String getFio() {
        return fio;
    }

    public void setFio(String fio) {
        this.fio = fio;
    }

    public Long getTabNum() {
        return tabNum;
    }

    public void setTabNum(Long tabNum) {
        this.tabNum = tabNum;
    }

    public Short getType() {
        return type;
    }

    public void setType(Short type) {
        this.type = type;
    }
     public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
    public void addTask(TaskEntity task) {
        this.getTasks().add(task);
    }

    public void dropTask(TaskEntity task) {
        this.getTasks().remove(task);
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof PersonEntity)) {
            return false;
        }
        PersonEntity other = (PersonEntity) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "ejb.PersonEntity[ id=" + id + " ]";
    }
    
}


Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
@Entity
@Table(name = "Task")
public class TaskEntity implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    
    private StatusEntity status;

   @JoinTable(name = "task_person", joinColumns = {
        @JoinColumn(name = "TASK_ID", referencedColumnName = "ID")}, inverseJoinColumns = {
        @JoinColumn(name = "PERSON_ID", referencedColumnName = "ID")})
    @ManyToMany 
   private Collection<PersonEntity> persons;

    
    public Collection<PersonEntity> getPersons() {
        return persons;
    }

    public void setPersons(Collection<PersonEntity> persons) {
        this.persons = persons;
    }

    @ManyToOne
    @JoinColumn(name="status_id") 
    public StatusEntity getStatus() {
        return status;
    }

    public void setStatus(StatusEntity status) {
        this.status = status;
    }
     
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public void addPerson(PersonEntity person) {
        this.getPersons().add(person);
    }

    public void dropPerson(PersonEntity person) {
        this.getPersons().remove(person);
    }

    public void addTMC(TMCEntity tmces) {
        this.getTmces().add(tmces);
    }

    public void dropTMC(TMCEntity tmces) {
        this.getTmces().remove(tmces);
    }
    
    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof TaskEntity)) {
            return false;
        }
        TaskEntity other = (TaskEntity) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "ejb.TaskEntity[ id=" + id + " ]";
    }
    
}



Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
@Entity
@Table(name = "Status")
public class StatusEntity implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    //@GeneratedValue(strategy = GenerationType.AUTO)
    private Short id;
    private String name;

    public StatusEntity() {
    }

    public StatusEntity(Short id, String name) {
        this.id = id;
        this.name = name;
    }
    
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "status")
    private Collection<TaskEntity> tasks;

    public Collection<TaskEntity> getTasks() {
        return tasks;
    }

    public void setTasks(Collection<TaskEntity> tasks) {
        this.tasks = tasks;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Short getId() {
        return id;
    }

    public void setId(Short id) {
        this.id = id;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof StatusEntity)) {
            return false;
        }
        StatusEntity other = (StatusEntity) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "ejb.StatusEntity[ id=" + id + " ]";
    }
    
}


Таблицы генерит нормально, для отношения многие-ко-многим создает промежуточную таблицу TASK_PERSON.
Создаю функцию вызова
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
@Stateful
public class RequestBean implements Request {
 
    @PersistenceContext(unitName = "Task-ejbPU")
    private EntityManager em;
 ...
public void createTask(String phoneSender, String phoneReciever, Long inventNumber) {
              logger.info("createTask");

        try {
            TaskEntity task = new TaskEntity();
           StatusEntity status = em.find(StatusEntity.class, (short)1);
           if(status==null)
           {
              status = createStatus("Создан", (short)1);
           }
           task.setStatus(status);
           status.getTasks().add(task);
 
            PersonEntity personSender = createPerson(phoneSender, (short)1);
            PersonEntity personReciever = createPerson(phoneReciever, (short)2);
              
             task.getPersons().add(personSender);
             task.getPersons().add(personReciever);
          //task.addPerson(personSender);
           // task.addPerson(personReciever);
            personSender.addTask(task); 
            personReciever.addTask(task);
         em.persist(task);
  
        } catch (Exception ex) {
            throw new EJBException(ex);
        }
    }

...
}


И тут возникает проблема с созданием и инициализацией коллекций.
При создании объекта StatusEntity, связанному с TaskEntity отношением один-ко-многим
Код: java
1.
2.
3.
4.
5.
6.
7.
StatusEntity status = em.find(StatusEntity.class, (short)1);
           if(status==null)
           {
              status = createStatus("Создан", (short)1);
           }
           task.setStatus(status);
           status.getTasks().add(task);


все ок.
В объекте status автоматом создается коллекция tasks и код
Код: java
1.
status.getTasks().add(task);


выполняется без проблем.

А вот при создании объектов PersonEntity
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
  PersonEntity personSender = createPerson(phoneSender, (short)1);
            PersonEntity personReciever = createPerson(phoneReciever, (short)2);
     
             
           task.getPersons().add(personSender);
             task.getPersons().add(personReciever);
          //task.addPerson(personSender);
           // task.addPerson(personReciever);
            personSender.addTask(task); 
            personReciever.addTask(task);

           em.persist(task);


в объекте task коллекция persons=null;
А в объектах PersonEntity personSender и personReciever коллекция tasks=null.
Т.е. автоматом при создании объекта под них не выделилась память.
И соответсвенно
Код: java
1.
2.
3.
4.
       task.getPersons().add(personSender);
             task.getPersons().add(personReciever);
            personSender.addTask(task); 
            personReciever.addTask(task);


тут вылазит исключение.

Что я делаю не так?
Почему при работе со StatusEntity при связи один-ко-многим коллекция автоинициализируется.
А при отношении с PersonEntity при связи многие-ко-многим - переменные коллекции так и остаются с null?
Объекты PersonEntity и TaskEntity создаются - проверено дебагером.
Код: java
1.
2.
         em.persist(task);
  


пробовал ставить в разные места и в конце и перед созданием PersonEntity, и после них - не помогает!
...
Рейтинг: 0 / 0
17.08.2012, 14:01:46
    #37920818
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JPA2 проблема с связанными коллекциями при отношении Многие-ко-многим
А так:
alex2808public class PersonEntity implements Serializable {
private Collection<TaskEntity> tasks = new ArrayList<TaskEntity>();



alex2808Т.е. автоматом при создании объекта под них не выделилась память.

facepalm
...
Рейтинг: 0 / 0
17.08.2012, 14:09:09
    #37920837
javapecker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JPA2 проблема с связанными коллекциями при отношении Многие-ко-многим
alex2808,
могу ошибаться, но тут:
Код: java
1.
StatusEntity status = em.find(StatusEntity.class, (short)1);


вы можете получить прокси от JPA провайдера вместо своего объекта, и прокси может вернуть свою инициализированную реализацию коллеции.
А если вы создаете класс самостоятельно, то JPA ничего о нем не знает и вы и ответственны за инициализацию коллекции, но вы даже не пытались это сделать.
...
Рейтинг: 0 / 0
17.08.2012, 14:12:10
    #37920845
alex2808
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JPA2 проблема с связанными коллекциями при отношении Многие-ко-многим
BlazkowiczА так:
alex2808public class PersonEntity implements Serializable {
private Collection<TaskEntity> tasks = new ArrayList<TaskEntity>();



alex2808Т.е. автоматом при создании объекта под них не выделилась память.

facepalm
Смотрел в примерах, нигде руцями не создается.
Все автоматом.
...
Рейтинг: 0 / 0
17.08.2012, 14:17:54
    #37920857
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JPA2 проблема с связанными коллекциями при отношении Многие-ко-многим
alex2808Все автоматом.
обычно промежуточная таблица не генерится а уже есть в БД.
Маппинг проще imho
...
Рейтинг: 0 / 0
17.08.2012, 14:20:36
    #37920863
javapecker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JPA2 проблема с связанными коллекциями при отношении Многие-ко-многим
Petro123,
Petro123обычно промежуточная таблица не генерится а уже есть в БД.
Ну это если начинать от БД, а тут судя по
alex2808 Таблицы генерит нормально, для отношения многие-ко-многим создает промежуточную таблицу
базы не было вообще
...
Рейтинг: 0 / 0
17.08.2012, 14:25:38
    #37920878
javapecker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JPA2 проблема с связанными коллекциями при отношении Многие-ко-многим
alex2808,
alex2808Смотрел в примерах, нигде руцями не создается.
Все автоматом.
где такие примеры?
Откуда в объекте который вы создали возьмется инициализированная коллекция, если вы ее не инициализировали?
...
Рейтинг: 0 / 0
17.08.2012, 14:29:54
    #37920885
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JPA2 проблема с связанными коллекциями при отношении Многие-ко-многим
alex2808Смотрел в примерах, нигде руцями не создается.

Примеры примерами, а лишнее null в коде - больше NPE в тестировании.
http://qconlondon.com/london-2009/presentation/Null+References:+The+Billion+Dollar+Mistake
Из вашего кода не понятно где что создаёт JPA, а где вы сами. Когда вы сами создаёте экземпляры, JPA ничего не может поделать с вашими объектами.

alex2808в объекте task коллекция persons=null;
А в объектах PersonEntity personSender и personReciever коллекция tasks=null.
А при отношении с PersonEntity при связи многие-ко-многим - переменные коллекции так и остаются с null?

Кто у вас null? Почему?
Уберите простыню. Локализуйте минимальный проблемный пример и давайте его обсудим.

Пока я вижу вот что

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
TaskEntity task = new TaskEntity();// Создаём объект. Ссылки на коллекции внутри - null, потому что так ф примерах и вообще руцями влом
...
task.setStatus(status); // Добавили статус
           status.getTasks().add(task);  // Добавили статус добавили таску в статус. Тоже довольно глупая ситуация, почему при двухсторонней связи надо все ссылки проставлять внешним методом. Инкапсуляция нарушена.
 
            PersonEntity personSender = createPerson(phoneSender, (short)1); // Создали каких-то персон
            PersonEntity personReciever = createPerson(phoneReciever, (short)2);  // Создали каких-то персон
              
             task.getPersons().add(personSender); //И вот здесь какой-то невероятной магией TaskEntity должна создать коллекцию persons, ведь в примерах так и руцями никто не делает.
             task.getPersons().add(personReciever);
...
Рейтинг: 0 / 0
17.08.2012, 14:32:12
    #37920891
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JPA2 проблема с связанными коллекциями при отношении Многие-ко-многим
javapecker,
ну да, согласен.
Я тс'а имел ввиду - "Для жизни создать все таблички, маппинг и всё будет под контролем"
...
Рейтинг: 0 / 0
17.08.2012, 14:39:02
    #37920895
javapecker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JPA2 проблема с связанными коллекциями при отношении Многие-ко-многим
Blazkowicz,

BlazkowiczИз вашего кода не понятно где что создаёт JPA, а где вы сами.
Предполагаю, что там где "em.", там JPA. Маловероятно что в методах типа createPerson тоже будет использоваться em, поскольку
Код: java
1.
private EntityManager em;


явно он в эти методы не передается
...
Рейтинг: 0 / 0
23.08.2012, 16:17:26
    #37928277
alex2808
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JPA2 проблема с связанными коллекциями при отношении Многие-ко-многим
Совет Blazkowicz помог решить проблему. Спасибо.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / JPA2 проблема с связанными коллекциями при отношении Многие-ко-многим / 11 сообщений из 11, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]