powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / JPA EclipseLink cascade CRUD
22 сообщений из 22, страница 1 из 1
JPA EclipseLink cascade CRUD
    #37661214
Joe R
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем привет.

Помогите разобраться с такой задачей. Работаю с JPA EclipseLink EJB. Есть две сущности Book и Author, связанные many-to-many. В базе данных таблицы books и authors связаны через join таблицу authors_books по их id. В таблице authors не должно быть дубликатов, т.е. при вставке сущности Book должна производится проверка для авторов. Если автора нет, то добавить его, если есть то не добавлять, а в join table добавить его id.
И вот тут непонятно как вклиниться в эту проверку, не разрывая каскадных связей. Как это лучше сделать?

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
@Entity
@Table(name="books")
public class Book implements Serializable {
	
	@Id
	@GeneratedValue(strategy=IDENTITY)
	@Column(name="book_id")
	private int bookId;

//bi-directional many-to-many association to Author
	@ManyToMany(fetch = EAGER, cascade = { MERGE, DETACH, REFRESH, PERSIST })
	@JoinTable(name = "authors_books", joinColumns = { @JoinColumn(name = "book_id") }, 
	inverseJoinColumns = { @JoinColumn(name = "author_id") })	
private List<Author> authors = new ArrayList<Author>();
.
.
.



Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
@Entity
@Table(name = "authors")
public class Author implements Serializable
{
	
	@Id
	@GeneratedValue(strategy = IDENTITY)
	@Column(name = "author_id")
	private int authorId;
@Column(unique = true)
	private String name;

	// bi-directional many-to-many association to Book
	@ManyToMany(fetch = EAGER, mappedBy = "authors", cascade = { MERGE, REFRESH, DETACH })
	private List<Book> books;
.
.
.



Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
@Stateless

public class BookServiceBean {
       
public Book create(Book entity)
	{		
		getEntityManager().persist(entity);
		return entity;
	}
.
.
.
}
...
Рейтинг: 0 / 0
JPA EclipseLink cascade CRUD
    #37661301
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Joe R,
ну дак код вставки и сохранения сессии то где?
Ты сделай сначала, чтобы они повторялись (запрос и покажи повтор).
...
Рейтинг: 0 / 0
JPA EclipseLink cascade CRUD
    #37661329
Joe R
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Petro123Joe R,
ну дак код вставки и сохранения сессии то где?
Ты сделай сначала, чтобы они повторялись (запрос и покажи повтор).

Код вставки я написал:
getEntityManager().persist(entity);

База MySQL. Поле name для авторов стоит уникальным. При добавлении дубликата вылетает DatabaseException.
...
Рейтинг: 0 / 0
JPA EclipseLink cascade CRUD
    #37661342
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Joe RБаза MySQL. Поле name для авторов стоит уникальным. При добавлении дубликата вылетает DatabaseException.
При этом authorId имеет значение, или null? Если имеет, то покажите польностью исключение. Если authorId null, то соответсвенно, как ORM узнает, что это сущствующая запись?
...
Рейтинг: 0 / 0
JPA EclipseLink cascade CRUD
    #37661389
Joe R
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
author_id генерится автоматом, вылетает на имени.


FINE: INSERT INTO authors (NAME) VALUES (?)
bind => [1 parameter bound]
FINE: SELECT 1
WARNING: Local Exception Stack:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'Joe Smith' for key 'ind_name'
Error Code: 1062
Call: INSERT INTO authors (NAME) VALUES (?)
bind => [1 parameter bound]
Query: InsertObjectQuery(Joe Smith)
...
Рейтинг: 0 / 0
JPA EclipseLink cascade CRUD
    #37661407
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Joe Rauthor_id генерится автоматом, вылетает на имени.

Я спрашиваю про authorId, а не author_id. В момент до вызова em.persist(). Это такой сложный вопрос?
...
Рейтинг: 0 / 0
JPA EclipseLink cascade CRUD
    #37661412
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Судя по
FINE: INSERT INTO authors (NAME) VALUES (?)
у вас во время сохранения книги, у автора не проставлен PK. Вот ОРМ и не знает что это существующий автор.
...
Рейтинг: 0 / 0
JPA EclipseLink cascade CRUD
    #37661448
Joe R
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот код создания сущности:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
....
Book book = new Book();
		book.setTitle("Title");
		book.setFileSize(10);
		book.setPagesCount(400);
		book.setPicture("pic" + rnd.nextInt(50) + ".jpg");
		book.setYear(2007 + rnd.nextInt(6));
		book.setDescription("Description");
		book.addAuthor(new Author("Joe Smith"));
		book.addAuthor(new Author("Randall Osborn"));

getEntityManager().persist(book);



authorId я не создаю, он в базе автоинкрементно генерится, это в сущности отображено:

Код: java
1.
2.
3.
4.
        @Id
	@GeneratedValue(strategy = IDENTITY)
	@Column(name = "author_id")
	private int authorId;



BlazkowiczСудя по
FINE: INSERT INTO authors (NAME) VALUES (?)
у вас во время сохранения книги, у автора не проставлен PK. Вот ОРМ и не знает что это существующий автор.

Вот в этом и вопрос, как этот РК создать то?
...
Рейтинг: 0 / 0
JPA EclipseLink cascade CRUD
    #37661451
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот таким нехитрым способом.
Код: java
1.
2.
book.addAuthor(findAuthor("Joe Smith"));
book.addAuthor(findAuthor("Randall Osborn"));
...
Рейтинг: 0 / 0
JPA EclipseLink cascade CRUD
    #37661474
Joe R
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowicz,

findAuthor('Joe Smith') это должен быть query типа?:

SELECT c FROM Author c WHERE c.name = 'Joe Smith'
...
Рейтинг: 0 / 0
JPA EclipseLink cascade CRUD
    #37661481
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Joe RfindAuthor('Joe Smith') это должен быть query типа?:
SELECT c FROM Author c WHERE c.name = 'Joe Smith'
Это, уж, как вам удобнее.
...
Рейтинг: 0 / 0
JPA EclipseLink cascade CRUD
    #37661503
Joe R
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А нет, проблема не в том, чтобы найти автора, а в том, чтобы добавить ссылку на него в таблицу authors_books. У меня ведь нет для неё сущности, ORM ведь должен сам разруливать каскадные зависимости. Что тут делать?
...
Рейтинг: 0 / 0
JPA EclipseLink cascade CRUD
    #37661512
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Joe RА нет, проблема не в том, чтобы найти автора, а в том, чтобы добавить ссылку на него в таблицу authors_books. У меня ведь нет для неё сущности, ORM ведь должен сам разруливать каскадные зависимости. Что тут делать?
ORM отлично разруливает. Если проблема не в том, а в этом, то объясните это а не то.
...
Рейтинг: 0 / 0
JPA EclipseLink cascade CRUD
    #37661589
Joe R
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В общем задача в следующем:
- если автор есть, то не добавлять его в таблицу authors, а добавить на него ссылку в таблицу authors_books, к которой у меня нет доступа. На SQL это выглядело бы так:

Код: sql
1.
INSERT INTO authors_books (author_id, book_id) VALUES ($author_id, $book_id)



Как это через ORM сделать?
...
Рейтинг: 0 / 0
JPA EclipseLink cascade CRUD
    #37661593
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Joe RА нет, проблема не в том, чтобы найти автора, а в том, чтобы добавить ссылку на него в таблицу authors_books. У меня ведь нет для неё сущности, ORM ведь должен сам разруливать каскадные зависимости. Что тут делать?
это многопользовательская система.
Представь что 2 чела рядом вводят
"Joe Smith"
- разные это авторы или один?
Т.е. код должен содержать findAuthor либо в Бизнес-слое вверху, либо внизу в сущности-DAO
...
Рейтинг: 0 / 0
JPA EclipseLink cascade CRUD
    #37661599
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Joe RВ общем задача в следующем:
- если автор есть, то не добавлять его в таблицу authors, а добавить на него ссылку в таблицу authors_books, к которой у меня нет доступа. На SQL это выглядело бы так:

Код: sql
1.
INSERT INTO authors_books (author_id, book_id) VALUES ($author_id, $book_id)


Как это через ORM сделать?
на SQL ты получишь райзе.
Т.е. тоже два запроса.
...
Рейтинг: 0 / 0
JPA EclipseLink cascade CRUD
    #37661628
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Joe RНа SQL это выглядело бы так:
Код: sql
1.
INSERT INTO authors_books (author_id, book_id) VALUES ($author_id, $book_id)


Как это через ORM сделать?
book.addAuthor(findAuthor(name));
...
Рейтинг: 0 / 0
JPA EclipseLink cascade CRUD
    #37661633
svenom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Joe RВ общем задача в следующем:
- если автор есть, то не добавлять его в таблицу authors, а добавить на него ссылку в таблицу authors_books, к которой у меня нет доступа. На SQL это выглядело бы так:
Код: sql
1.
INSERT INTO authors_books (author_id, book_id) VALUES ($author_id, $book_id)


Как это через ORM сделать?Господи, да что у вас за проблема то? Вам не надо руками ничего добавлять в эту промежуточную таблицу. Вам надо просто добавить в список авторов еще одного автора. Все остальное JPA сделает за вас.
Но! Разумеется, вы не можете сделать что-то типа
Код: java
1.
2.
3.
Author a = new Author("John Smith");
book.getAuthors().add(a);
em.persist(book);

Ведь в этом случае, будет создан новый автор, а судя по вот этому исключению:
logcom.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'Joe Smith' for key 'ind_nameимена авторов у вас должны быть уникальными.
Вам Blazkowicz уже правильно сказал, что вам требуется сделать - вместо создания нового автора, сначала производить поиск сущеуствующего.
То есть надо делать что-то типа (псведокод):
Код: java
1.
2.
3.
4.
5.
6.
7.
Author a = findAuthorByName("John Smith");
if (a == null) {
    a = new Author("John Smith");
    em.persist(a);
}
book.getAuthors.add(a);
em.book(persist);

Если ваши маппинги прописаны верно, то такой вариант отработает на ура.
...
Рейтинг: 0 / 0
JPA EclipseLink cascade CRUD
    #37661640
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svenomТо есть надо делать что-то типа (псведокод):

Персистить, автора при создании, не обязательно, если каскада прописаны. Само добавит.
...
Рейтинг: 0 / 0
JPA EclipseLink cascade CRUD
    #37661915
Joe R
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Разобрался, сделал findAuthorByName и заработало.
Всем спасибо за помощь.
...
Рейтинг: 0 / 0
JPA EclipseLink cascade CRUD
    #37661961
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати, никогд ане понимал почему
findAuthorByName(String name)
может быть лучше чем
findAuthor(String name)
...
Рейтинг: 0 / 0
JPA EclipseLink cascade CRUD
    #37661999
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторКстати, никогд ане понимал почему
findAuthorByName(String name)
может быть лучше чем
findAuthor(String name)

А если есть потребность в findAuthorByBookName(String bookName) или findAuthorByBookISDN(String ISDN)?
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / JPA EclipseLink cascade CRUD
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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