Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate Session, EJB и дубликаты сущностей. / 20 сообщений из 20, страница 1 из 1
04.03.2012, 16:47:30
    #37690673
Joe R
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate Session, EJB и дубликаты сущностей.
Всем привет.

Есть 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
05.03.2012, 13:24:15
    #37691450
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate Session, EJB и дубликаты сущностей.
маппинг для Book где?
sql log включили? Запрос посмотрели?
...
Рейтинг: 0 / 0
05.03.2012, 19:30:31
    #37692264
Joe R
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate Session, EJB и дубликаты сущностей.
Код: 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
05.03.2012, 19:50:12
    #37692292
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate Session, EJB и дубликаты сущностей.
...
Рейтинг: 0 / 0
05.03.2012, 19:55:03
    #37692295
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate Session, EJB и дубликаты сущностей.
насколько я понял вот это может помочь criteria.setProjection(Projections.distinct(Projections.property("id")));
...
Рейтинг: 0 / 0
05.03.2012, 19:57:47
    #37692298
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate Session, EJB и дубликаты сущностей.
или вот это .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
...
Рейтинг: 0 / 0
06.03.2012, 14:37:32
    #37693537
Joe R
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate Session, EJB и дубликаты сущностей.
Точно, это из-за outer join дубликаты появляются, т. к. идут запросы для дочерних элементов (авторов книги).
setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY) избавляется от дубликатов, но только в памяти, из базы они всё равно идут. Я так понял, что в случае если используется setFirstResult() и setMaxResults() нужно делать отдельные селекты для дочерних элементов. Это делается через criteria.setFetchMode("authors", FetchMode.SELECT). Тогда из базы нет дубликатов.
...
Рейтинг: 0 / 0
06.03.2012, 14:50:26
    #37693554
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate Session, EJB и дубликаты сущностей.
Joe R,
а почему у тебя 2 таблы вместо одной
author2_, author3_
...
Рейтинг: 0 / 0
06.03.2012, 14:51:50
    #37693558
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate Session, EJB и дубликаты сущностей.
Petro123Joe R,
а почему у тебя 2 таблы вместо одной
author2_, author3_
Ну, ManyToMany, же.
...
Рейтинг: 0 / 0
06.03.2012, 15:02:03
    #37693588
Joe R
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate Session, EJB и дубликаты сущностей.
Кстати, слышал, что ManyToMany это не оптимальный мэппинг. Вроде как эффективнее JoinTable выносить в отдельную сущность и работать с двумя OneToMany мэппингами.
Какие есть мнения по этому поводу?
...
Рейтинг: 0 / 0
06.03.2012, 15:20:56
    #37693626
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate Session, EJB и дубликаты сущностей.
BlazkowiczPetro123Joe R,
а почему у тебя 2 таблы вместо одной
author2_, author3_
Ну, ManyToMany, же.
у него ManyToMany промежуточная из 2-х = Книги_Авторы

Joe R,
да
...
Рейтинг: 0 / 0
06.03.2012, 15:25:20
    #37693638
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate Session, EJB и дубликаты сущностей.
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
06.03.2012, 15:37:06
    #37693674
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate Session, EJB и дубликаты сущностей.
Petro123у него ManyToMany промежуточная из 2-х = Книги_Авторы

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

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

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


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