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

Есть DAO слой на JPA и EJB, всё работает.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
public abstract class GenericDAOJPA<T> implements IGenericDAO<T>
{
	@PersistenceContext(unitName = "BookStore")
	private EntityManager em;

	
	public EntityManager getEntityManager()
	{
		return em;
	}


	@Override
	public void create(T entity)
	{
		em.persist(entity);
	}
......................................



Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
@Stateless(name="BookDAOJPA")
@LocalBean
@Local(IBookDAO.class)
public class BookDAOJPA extends GenericDAOJPA<Book> implements IBookDAO
{

................................
public List<Book> getBooks()
       {
                Session session = getEntityManager().unwrap(Session.class);
                
		Criteria crit = session.createCriteria(Book.class);
		crit.setFirstResult(1);
		crit.setMaxResults(10);
		@SuppressWarnings("unchecked")
		List<Book> results = crit.list();

		return results;
	}
.....................................
}



Решил делать запросы через объектные критерии. JPA Criteria API это вывих мозга показался мне, критерии Hibernate гораздо приятнее. Получаю сессию через
Session session = getEntityManager().unwrap(Session.class);
в методе getBooks(), и в итоге у меня список с дубликатами сущностей. Например, должно быть 10 разных записей, а получается вот так:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
book1
book1
book2
book2
book3
book3
book4
book4
book5
book5





Что я делаю не правильно?
...
Рейтинг: 0 / 0
Hibernate Session, EJB и дубликаты сущностей.
    #37691450
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
маппинг для Book где?
sql log включили? Запрос посмотрели?
...
Рейтинг: 0 / 0
Hibernate Session, EJB и дубликаты сущностей.
    #37692264
Joe R
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: 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.
@Entity
@Table(name="books")
public class Book implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy=IDENTITY)
	@Column(name="book_id")
	private int bookId;

	private String description;

	@Column(name="file_size")
	private int fileSize;

	@Column(name="pages_count")
	private int pagesCount;

	private String picture;

	private String title;

	private int year;

	//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 Set<Author> authors = new HashSet<Author>();
	//bi-directional many-to-one association to BookType
    @ManyToOne(fetch = EAGER)
	@JoinColumn(name="type_id")
	private BookType bookType;

..................{getters, setters}..................



В SQL логе ничего особенного:
Код: sql
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.
select
        this_.book_id as book1_1_2_,
        this_.type_id as type8_1_2_,
        this_.description as descript2_1_2_,
        this_.file_size as file3_1_2_,
        this_.pages_count as pages4_1_2_,
        this_.picture as picture1_2_,
        this_.title as title1_2_,
        this_.year as year1_2_,
        authors2_.book_id as book1_1_4_,
        author3_.author_id as author2_4_,
        author3_.author_id as author1_2_0_,
        author3_.name as name2_0_,
        booktype4_.type_id as type1_0_1_,
        booktype4_.type as type0_1_ 
    from
        books this_ 
    left outer join
        authors_books authors2_ 
            on this_.book_id=authors2_.book_id 
    left outer join
        authors author3_ 
            on authors2_.author_id=author3_.author_id 
    left outer join
        book_type booktype4_ 
            on this_.type_id=booktype4_.type_id limit ?, ?|#]



Запросы через JPA работают прекрасно, дубликаты появляюстя только в родной сессии hibernate.
...
Рейтинг: 0 / 0
Hibernate Session, EJB и дубликаты сущностей.
    #37692292
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Hibernate Session, EJB и дубликаты сущностей.
    #37692295
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
насколько я понял вот это может помочь criteria.setProjection(Projections.distinct(Projections.property("id")));
...
Рейтинг: 0 / 0
Hibernate Session, EJB и дубликаты сущностей.
    #37692298
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
или вот это .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
...
Рейтинг: 0 / 0
Hibernate Session, EJB и дубликаты сущностей.
    #37693537
Joe R
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Точно, это из-за outer join дубликаты появляются, т. к. идут запросы для дочерних элементов (авторов книги).
setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY) избавляется от дубликатов, но только в памяти, из базы они всё равно идут. Я так понял, что в случае если используется setFirstResult() и setMaxResults() нужно делать отдельные селекты для дочерних элементов. Это делается через criteria.setFetchMode("authors", FetchMode.SELECT). Тогда из базы нет дубликатов.
...
Рейтинг: 0 / 0
Hibernate Session, EJB и дубликаты сущностей.
    #37693554
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Joe R,
а почему у тебя 2 таблы вместо одной
author2_, author3_
...
Рейтинг: 0 / 0
Hibernate Session, EJB и дубликаты сущностей.
    #37693558
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123Joe R,
а почему у тебя 2 таблы вместо одной
author2_, author3_
Ну, ManyToMany, же.
...
Рейтинг: 0 / 0
Hibernate Session, EJB и дубликаты сущностей.
    #37693588
Joe R
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кстати, слышал, что ManyToMany это не оптимальный мэппинг. Вроде как эффективнее JoinTable выносить в отдельную сущность и работать с двумя OneToMany мэппингами.
Какие есть мнения по этому поводу?
...
Рейтинг: 0 / 0
Hibernate Session, EJB и дубликаты сущностей.
    #37693626
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczPetro123Joe R,
а почему у тебя 2 таблы вместо одной
author2_, author3_
Ну, ManyToMany, же.
у него ManyToMany промежуточная из 2-х = Книги_Авторы

Joe R,
да
...
Рейтинг: 0 / 0
Hibernate Session, EJB и дубликаты сущностей.
    #37693638
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123,
если так, то хибер сгенерит ОДНУ таблу и там будут повторы.
Код: 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.
@Entity
public class Book {
	@Id
	@Column(name = "id")
	@GeneratedValue(strategy = GenerationType.ALL)
	private Long id;
	@Column(nullable = false)
	private String Name;
	@ManyToMany(cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
	@JoinTable(name = "A_B", joinColumns = @JoinColumn(name = "B_ID"), inverseJoinColumns = @JoinColumn(name = "A_ID"))
	private List<Autor> autorors = new ArrayList<Autor>();
	.......
		public void addAutor(Autor autor) {
		autor.getBooks().add(this);
		getAutorors().add(autor);
	}
}

@Entity
public class Autor {
	@Id
	@Column(name = "id")
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
	@Column(nullable = false)
	private String Name;
	@ManyToMany(fetch = FetchType.LAZY)
	@JoinTable(name = "A_B", joinColumns = @JoinColumn(name = "A_ID"), inverseJoinColumns = @JoinColumn(name = "B_ID"))
	private List<Book> books  = new ArrayList<Book>();
}
----------------------
    create table A_B (
        A_ID int8 not null,
        B_ID int8 not null
    )

    create table Autor (
        id  bigserial not null,
        Name varchar(255) not null,
        primary key (id)
    )

    create table Book (
        id  bigserial not null,
        Name varchar(255) not null,
        primary key (id)
    )

    alter table A_B 
        add constraint FKFFC45F71CDFD 
        foreign key (B_ID) 
        references Book

    alter table A_B 
        add constraint FKFFC489586CE0 
        foreign key (A_ID) 
        references Autor
-----------------------

...
Рейтинг: 0 / 0
Hibernate Session, EJB и дубликаты сущностей.
    #37693674
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123у него ManyToMany промежуточная из 2-х = Книги_Авторы

books - this_
authors_books - authors2_
authors - author3_
Где ты ещё увидел?
...
Рейтинг: 0 / 0
Hibernate Session, EJB и дубликаты сущностей.
    #37693682
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,
да, ты прав... псевдонимы... глаза сломаешь 8-)
a,b,a_b
...
Рейтинг: 0 / 0
Hibernate Session, EJB и дубликаты сущностей.
    #37693688
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну и, к слову, "авторы книги" это book authors, а не authors books.
...
Рейтинг: 0 / 0
Hibernate Session, EJB и дубликаты сущностей.
    #37693716
Joe R
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowicz,

Да, логичнее.
А в чём заключается эффективность OneToMany по сравнению с ManyToMany? SQL запросов меньше?
...
Рейтинг: 0 / 0
Hibernate Session, EJB и дубликаты сущностей.
    #37693727
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Joe R,
- обычно а_b начинает обрастать полями и превращаться в сущность-класс
- в реальной продакшен БД уже есть такая табла
- у меня не вышло без дублей в БД выше кодом
...
Рейтинг: 0 / 0
Hibernate Session, EJB и дубликаты сущностей.
    #37693746
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Joe RА в чём заключается эффективность OneToMany по сравнению с ManyToMany? SQL запросов меньше?
Не знаю. Используем ManyToMany, где нужно. Проблем особых небыло. Где-то читал мнение, что в большинстве случаев в таблице ассоциации со временем будут вознкать дополнительные поля. Например, в вашем случае, порядоковый номер, для строгого упоминания авторов книги в определенном порядке. Тогда уже приходится заводить сущность для этой таблицы. Соответсвенно, почему бы не заложится на это сразу.
...
Рейтинг: 0 / 0
Hibernate Session, EJB и дубликаты сущностей.
    #37693783
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторА в чём заключается эффективность OneToMany по сравнению с ManyToMany? SQL запросов меньше?
Ну насчет эффективности можно рассуждать годами, а вот упрощение логики - это убийственное преимущество при любом раскладе
...
Рейтинг: 0 / 0
Hibernate Session, EJB и дубликаты сущностей.
    #37693796
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторНе знаю. Используем ManyToMany, где нужно. Проблем особых небыло. Где-то читал мнение, что в большинстве случаев в таблице ассоциации со временем будут вознкать дополнительные поля. Например, в вашем случае, порядоковый номер, для строгого упоминания авторов книги в определенном порядке. Тогда уже приходится заводить сущность для этой таблицы. Соответсвенно, почему бы не заложится на это сразу.

еще часто возникают проблемы с каскадностью
...
Рейтинг: 0 / 0
20 сообщений из 20, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate Session, EJB и дубликаты сущностей.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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