powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / [Hibernate] Эмуляция связи многие-ко-многим (связующая таблица с параметром)
12 сообщений из 12, страница 1 из 1
[Hibernate] Эмуляция связи многие-ко-многим (связующая таблица с параметром)
    #38028599
IDVsbruck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В принципе, это не эмуляция, а ручное создание такой связи через вручную созданную связующую таблицу. Назвал эмуляцией, потому что нужна не двунаправленная связь, а только лишь связка в этой связующей таблице.

Связываю объекты Box и Pen.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
@Entity
@Table(name = "box")
public class Box implements Serializable {
	@Id
	@Column(name = "id")
	@GeneratedValue(strategy = GenerationType.AUTO)
	private long id;
}

@Entity
@Table(name = "pen")
public class Pen implements Serializable {
	@Id
	@Column(name = "id")
	@GeneratedValue(strategy = GenerationType.AUTO)
	private long 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.
@Entity
@Table(name = "box__pen")
public class boxPen implements Serializable {
	@Id
	@Column(name = "box_id")
	private long boxId;

	@Id
	@Column(name = "pen_id")
	private long penId;

	@ManyToOne
	@JoinColumn(name = "box_id", referencedColumnName = "id")
	private Box box;

	@ManyToOne
	@JoinColumn(name = "pen_id", referencedColumnName = "id")
	private Pen pen;

	@Column(name = "color", length = 16)
	private String color;

	@Override
	public int hashCode() {...}
	@Override	 
	public boolean equals(Object object) {...}
	...
}


В контроллере создаю объект boxPen и записываю:
Код: java
1.
2.
3.
4.
5.
6.
7.
	...
	BoxPen boxPen = new BoxPen();
	boxPen.setBox(box);
	boxPen.setPen(pen);
	boxPen.setColor("red");
	someDAO.put(boxPen);
	...


Непосредственно при записи получаю лог запросов и исключение:
авторHibernate: select boxpen0_.box_id as box1_21_0_, boxpen0_.pen_id as pen2_21_0_, boxpen0_.color as color21_0_ from box__pen boxpen0_ where boxpen0_.box_id=? and boxpen0_.pen_id=?
Hibernate: select box0_.id as id20_1_, ..., from box box0_ where box0_.id=?
Hibernate: insert into box__pen(color, pen_id, box_id) values (?, ?, ?)
11:38:52,691 WARN SqlExceptionHelper:143 - SQL Error: 0, SQLState: S1093
11:38:52,691 ERROR SqlExceptionHelper:144 - The index 4 is out of range.
com.microsoft.sqlserver.jdbc.SQLServerException: The index 4 is out of range.
Попытка вставлять сразу id вместо объектов только выдает аналогичное исключение, не делая запросы.

Попробовал перейти к "элегантному" описанию связующей таблицы:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
@Entity
@Table(name = "box__pen")
public class boxPen implements Serializable {
	@Id
	@ManyToOne
	@JoinColumn(name = "box_id", referencedColumnName = "id")
	private Box box;

	@Id
	@ManyToOne
	@JoinColumn(name = "pen_id", referencedColumnName = "id")
	private Pen pen;

	@Column(name = "color", length = 16)
	private String color;

	@Override
	public int hashCode() {...}
	@Override	 
	public boolean equals(Object object) {...}
	...
}


Создаю и записываю экземпляр:
авторHibernate: select boxpen0_.box_id as box2_21_0_, boxpen0_.pen_id as pen3_21_0_, boxpen0_.color as color21_0_ from box__pen boxpen0_ where boxpen0_.box_id=? and boxpen0_.pen_id=?
Hibernate: insert into box__pen (color, box_id, pen_id) values (?, ?, ?)
11:49:51,738 WARN SqlExceptionHelper:143 - SQL Error: 515, SQLState: 23000
11:49:51,738 ERROR SqlExceptionHelper:144 - Cannot insert the value NULL into column 'box_id', table 'sdb.dbo.box__pen'; column does not allow nulls. INSERT fails.
7 лист 2012 11:49:51 org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [springmvc] in context with path [/work] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: Cannot insert the value NULL into column 'box_id', table 'sdb.dbo.box__pen'; column does not allow nulls. INSERT fails.; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: Cannot insert the value NULL into column 'box_id', table 'sdb.dbo.box__pen'; column does not allow nulls. INSERT fails.] with root cause
com.microsoft.sqlserver.jdbc.SQLServerException: Cannot insert the value NULL into column 'box_id', table 'sdb.dbo.box__pen'; column does not allow nulls. INSERT fails.
Если реализовать в объектах Box и Pen обратные связи @OneToMany, то все нормально работает.
А, да, добавление или удаление атрибутов "insertable = false" и "updatable = false" ни к чему не приводят.

Прошу помощи в решении данного вопроса. Спасибо.
...
Рейтинг: 0 / 0
[Hibernate] Эмуляция связи многие-ко-многим (связующая таблица с параметром)
    #38028710
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IDVsbruck,

Чем не нравится классика и зачем велосипед, ты так и не ответил.
...
Рейтинг: 0 / 0
[Hibernate] Эмуляция связи многие-ко-многим (связующая таблица с параметром)
    #38028758
IDVsbruck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну, давай отталкиваться от того, что мне хочется реализовать составной внешний ключ, пусть для самообразования, а он не поддается. Все вводные привел, получаю исключения.
...
Рейтинг: 0 / 0
[Hibernate] Эмуляция связи многие-ко-многим (связующая таблица с параметром)
    #38028795
Фотография grasoff.net
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторCannot insert the value NULL into column 'box_id', table 'sdb.dbo.box__pen'; column does not allow nullsсделать поле box_id nullable
делофто
...
Рейтинг: 0 / 0
[Hibernate] Эмуляция связи многие-ко-многим (связующая таблица с параметром)
    #38028895
IDVsbruck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не, "Allow Nulls property cannot be set on a column which is part of the primary key".
Через Entity если проставить nullable = true просто проходит компиляция, но ключевые поля, само собой, "Not Allows NULL".
...
Рейтинг: 0 / 0
[Hibernate] Эмуляция связи многие-ко-многим (связующая таблица с параметром)
    #38028958
Фотография grasoff.net
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
дак следующий же вывод очень простой
убери @id
из второго варианта boxPen
...
Рейтинг: 0 / 0
[Hibernate] Эмуляция связи многие-ко-многим (связующая таблица с параметром)
    #38028967
IDVsbruck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тогда нельзя откомпилировать - требует наличие идентефикатора.
...
Рейтинг: 0 / 0
[Hibernate] Эмуляция связи многие-ко-многим (связующая таблица с параметром)
    #38028993
Фотография grasoff.net
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IDVsbruckТогда нельзя откомпилировать - требует наличие идентефикатора.
сделай идентификатор )
...
Рейтинг: 0 / 0
[Hibernate] Эмуляция связи многие-ко-многим (связующая таблица с параметром)
    #38029263
IDVsbruck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Согласен, костыли можно всякие вставлять. Но почему такая проблема с составным внешним ключом? - Ведь все должно быть просто и примитивно! Прям фигня какая-то! - Уже такие пляски с бубном устраиваю ...
...
Рейтинг: 0 / 0
[Hibernate] Эмуляция связи многие-ко-многим (связующая таблица с параметром)
    #38029300
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IDVsbruck,
Составные это геморрой т.к отсутствует первичный ключ PK в обоих таблицах
...
Рейтинг: 0 / 0
[Hibernate] Эмуляция связи многие-ко-многим (связующая таблица с параметром)
    #38029379
pavel_nv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IDVsbruck,

маппинг с составным ключом делается так:

Box, Pen - аналогично Вашему

Сначало описываем ключ (Так как ключ должен быть уникальным для таблицы и реализовать Serializable (для методов get/load/save...))
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
@Embeddable
public class BoxPenId implements Serializable {
    @ManyToOne(targetEntity=Pen.class)
    private Pen pen;
    @ManyToOne(targetEntity=Box.class)
    private Box box;

    //getters and setters
}



и потом собственно таблицу:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
@Entity
public class BoxPen implements Serializable {
    @EmbeddedId
    private BoxPenId boxPenId;
    
    @Column
    private String color;   
    
    //getters and setters
}



ну и для теста:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
        Box box = new Box();
        boxService.create(box);
        Pen pen = new Pen();
        penService.create(pen);
        
        BoxPenId bpId = new BoxPenId();
        bpId.setBox(box);
        bpId.setPen(pen);
        
        BoxPen boxPen = new BoxPen();
        boxPen.setBoxPenId(bpId);
        boxPen.setColor("red");
        boxPenService.create(boxPen);



в логах я увидел желаемое:
Hibernate: insert into box values ( )
Hibernate: insert into pen values ( )
Hibernate: insert into BoxPen (color, box_id, pen_id) values (?, ?, ?)
...
Рейтинг: 0 / 0
[Hibernate] Эмуляция связи многие-ко-многим (связующая таблица с параметром)
    #38029438
IDVsbruck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pavel_nv, низкий поклон тебе. Я за сегодня натыкался раз 100, наверное, на то, что использовали либо такую конструкцию, либо аннотицию @ClassId. Но думал: вот дураки, используют еще один дополнительный класс. Думаю, или даже уверен, что можно выкрутиться и реализовать все в одном, но так вроде максимально кошерно. Плюс надо в классе составного идентефикатора переопределить hashCode и equals, а также для удобства можно добавить Transient поля для зависимых сущностей, дабы скрыть от контроллера удлинившуюся цепочку полей и методов, хотя в HQL-запросе все-таки надо строить полную цепь. Спасибо.
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / [Hibernate] Эмуляция связи многие-ко-многим (связующая таблица с параметром)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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