Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate, наследование / 24 сообщений из 24, страница 1 из 1
23.05.2012, 00:40
    #37806922
slippery
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, наследование
Добрый вечер, у меня в проекте используется хибернат. Все сущности наследуются от одной способом: InheritanceType.SINGLE_TABLE , но поля не в той же таблице, а в соответствующих которые подключаются с помощью @SecondaryTable

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "types", discriminatorType = DiscriminatorType.STRING)
public abstract class ObjEntity …...


@Entity
@SecondaryTable(name="user"
public class User .......ь сущность) соответственно если обратиться к этому полю в запросе или вынут
@Column(table = "user")
private String name;

…..........................


так вот, у меня есть задачи в которых конкретный класс сразу неизвестен, и приходится писать общего предка ( ObjEntity ) соответственно если обратиться к этому полю в запросе или вынуть сущность у которой стоит такое поле атрибутом, то хибернат сделает запрос ко всем сущностям проекта расширяющихся от ObjEntity и та у которой id совпадет ту и вернет. Я слышал что есть какой-то способ решение этой проблемы но так его и не нашел.
Может кто-то уже сталкивался с таким?
...
Рейтинг: 0 / 0
23.05.2012, 01:13
    #37806944
slippery
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, наследование
при вставке, произошол какой-то глюк, приведу иерархию в пример еще раз:

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "types", discriminatorType = DiscriminatorType.STRING)
public abstract class ObjEntity {
................................
}


@Entity
@SecondaryTable(name="user"
public class User extend ObjEntity {
@Column(table = "user")
private String name;
..........................................
}
...
Рейтинг: 0 / 0
23.05.2012, 01:26
    #37806951
IDVsbruck
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, наследование
Или я не очень правильно понял твой вопрос, или ты несколько усложняешь себе жизнь, когда можно было бы сделать все несколько проще и переложить всю грязную и сложную работу на хибер.

Предок и в то же время сущность, хранящая общие поля:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
@Entity
@Table(name = "objEntity")
@Inheritance(strategy = InheritanceType.JOINED)
public class ObjEntity implements Serializable {
	@Id
	@Column(name = "id")
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;

	@Column(name = "someField")
	private Integer someField;
...
}


наследники:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
@Entity
@Table(name = "user")
public class User extends ObjEntity {
	@Column(name = "someField1")
	private Integer someField1;
...
}
@Entity
@Table(name = "visitor")
public class Visitor extends ObjEntity {
	@Column(name = "someField2")
	private Integer someField2;
...
}


Если класс точно известен, то искать можно сразу в нужном наследнике, причем, при поиске в user можно использовать поле someField предка.
Если нет, то можно искать в предке. И хотя вернет лист/объект типа ObjEntity, но typeof покажет реальный класс объекта - User или Visitor.
О какой проблеме ты говоришь, не очень понимаю и представляю. Применил такую структуру для регистрационных таблиц (базовая, фейсбук, твиттер, гугл и т.д.) и в зависимости от задачи выбираю или из нужного наследника, или из предка.
...
Рейтинг: 0 / 0
23.05.2012, 01:29
    #37806953
IDVsbruck
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, наследование
P.S. Не видел твою поправку, писал ответ. У меня почти то же самое, но проблемы не вижу и не понимаю ее смысл.
...
Рейтинг: 0 / 0
23.05.2012, 02:06
    #37806969
slippery
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, наследование
IDVsbruck,

попробуй обратиться вот так: session.get(ObjEntity.class, 1) в этом случаи хибернта сделает джоин 3х таблиц: ObjEntity, User, Visitor и вернет ту где ид = 1.
Задача сделать так чтоб он не делал этого джойна, а сразу обратился к нужной таблице.

Пояснение к задаче, есть у меня в проекте такие моменты, где надо указывать родительский класс, а не конкретный, к примеру есть таблица связи в которой можно логически связать 2 любых объекта, будь-то пользователь и документ или документ и карта и т.д. вот в таких местах и приходится писать общего предка ObjEntity

Я использую тип наследования: иерархия класса в 1 таблице, но разношу поля по до подключенным, на внешний вид похоже на InheritanceType.JOINED, но есть НО, у меня есть дискриминатор в котором указана имя сущности-таблицы с доп полями.

То есть ObjEntity кроме ид у меня хранится и имя сущности соответствующей этому ид, к приvеру:
1 User
2 Visitor

Это стандартный механизм в хибернате. Так вот я слышал, что можно каким то способом, когда используется такой вид наследования сделать так, что при обращении session.get(ObjEntity.class, 1) будет делать конкретное обращение к конкретной таблицы, а не поиск по всем где ид совпадет.

Надеюсь понятно расписал)
...
Рейтинг: 0 / 0
23.05.2012, 13:10
    #37807682
IDVsbruck
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, наследование
Совершенно непонятно. Стало еще запутанней.
...
Рейтинг: 0 / 0
23.05.2012, 13:16
    #37807698
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, наследование
Может отложить в сторону Hibernate и просто подумать а как именно вы хотели бы видеть поиск по колонке, когда не известно имя таблицы?
Может какую-нибудь view тогда сделать с union по всем наследникам?
...
Рейтинг: 0 / 0
24.05.2012, 13:37
    #37809682
slippery
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, наследование
Давайте на коде покажу что хочется добиться и тогда будет ясно)

Код: 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.
@Entity
@Table(name = "objEntity")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING)
public class ObjEntity implements Serializable {
	@Id
	private Long id;
...
}

@Entity
@Table(name = "user")
public class User extends ObjEntity {
	@Column(name = "someField1")
	private Integer someField1;
...
}
@Entity
@Table(name = "visitor")
public class Visitor extends ObjEntity {
	@Column(name = "someField2")
	private Integer someField2;
...
}

SessionFactory factory = ...................
Session session = factory.openSession()

User user = new User();
....
Visitor visitor = new Visitro();
...

session.merge(user);
session.merge(visitor);

session. get(ObjEntity, 1), где 1 - это к примеру идентификатор созданного пользователя



и тут хибернат сделает селект по objEntity и приджойнит и user и visitor и вернет ту у которой совпадет ид. Это дефолтовая логика. Но я слышал, что есть решения, как сделать в хибернате так, чтоб при запросе session. get(ObjEntity, 1)(при запросе к родительской сущности) , он посмотрел на дискриминатор "type" и прийджойнил только конкретную таблицу. Вот вопрос в этом, как в хибернате такое сделать?
...
Рейтинг: 0 / 0
24.05.2012, 14:24
    #37809802
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, наследование
Так понятнее дискриминатор я сразу и не приметил.
...
Рейтинг: 0 / 0
24.05.2012, 14:27
    #37809808
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, наследование
А давайте вы теперь определитесь с маппингом. Вам JOINED ведь нужен. Почему везде SINGLE_TABLE написано?
...
Рейтинг: 0 / 0
24.05.2012, 14:31
    #37809824
slippery
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, наследование
Blazkowicz,

нет мне JOINED не нужен, я и не его писал сразу в первом посте, у меня в проекте(еще до меня) все сущности от InheritanceType.SINGLE_TABLE.

а мне теперь на уже существующей структуре из больше чем 200 сущностей нужно сделать чтоб при запросе к родителю, такого громадного джойна не было. Задача у меня такая)

Да, в уточнение при InheritanceType.SINGLE_TABLE

прошу прощения из примера в этом же топике копировал код и упустил момент, в потомках надо вместо @Table, @SecondaryTable использовать, или работать не будет. то есть:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
@Entity
@Table(name = "objEntity")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING)
public class ObjEntity implements Serializable {
	@Id
	private Long id;
...
}

@Entity
@SecondaryTable(name = "user")
public class User extends ObjEntity {
	@Column(table ="user", name = "someField1")
	private Integer someField1;
...
}



Вот теперь точный пример, еще раз очень извиняюсь. Жду помощи)
...
Рейтинг: 0 / 0
24.05.2012, 14:33
    #37809831
IDVsbruck
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, наследование
Может, что-то и есть, но так ли оно нужно?
В твоем приведенном случае какой тип будет иметь переменная, которая получает session. get(ObjEntity, 1)? (понятно, мы ее определили как ObjEntity) Но вот после переопределения она уже будет User. Поэтому банально, зная, что ты хочешь пройтись по таблице user, проверяешь:
Код: java
1.
2.
ObjEntity obj = session. get(ObjEntity.class, 1);
if (obj instanceof User) System.out.println("It's User!");



Второй вариант. Я его сначала не использовал, так как он избыточен, но для использовании в представлении оказался удобнее - у предка сразу указывать тип записи (похоже, ручная реализация искомого тобой дискриминатора):
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
@Entity
@Table(name = "objEntity")
@Inheritance(strategy = InheritanceType.JOINED)
public class ObjEntity implements Serializable {
	@Id
	@Column(name = "id")
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;

	@Enumerated(EnumType.STRING)
	@Column(name = "type")
	private TableType type;
...
}

public enum TableType implements Serializable {
	USER, VISITOR;
}


Тогда
Код: java
1.
2.
ObjEntity obj = session. get(ObjEntity.class, 1);
if (obj.type == USER) System.out.println("It's User!");


или
Код: java
1.
User obj = (User) session. createQuery("FROM ObjEntity obj WHERE obj.id = :id AND obj.type = :type").setLong("id", 1).setString("type", TableType.USER).uniqueResult();



Хотя, возможно, ты и прав - если есть механизм, автоматически реализующий задуманное, то наверняка он лучший.
Правда, он автоматически становится ненужным, если сработает такое (не проверял, но почему-то уверен, что работает):
Код: java
1.
2.
3.
User user = session. get(User.class, 1);//вернет значение
user = session. get(User.class, 2);//вернет null
Visitor visitor = session.get(Visitor.class, 2);//вернет значение


И этот дескриптор оказывается ненужным.
...
Рейтинг: 0 / 0
24.05.2012, 14:37
    #37809841
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, наследование
А можно теперь запрос посмотреть, которых хибер генерит? Он все-все таблицы джоинит? А это действительно сказывается на производительности?
...
Рейтинг: 0 / 0
24.05.2012, 14:37
    #37809842
slippery
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, наследование
IDVsbruck,

проблема в том, что при запросе ObjEntity obj = session. get(ObjEntity.class, 1);
хибер делает джоин всех сущностей наследуемых от ObjEntity, в моем случаи это больше чем 200 джойнов))) как это победить?
...
Рейтинг: 0 / 0
24.05.2012, 14:39
    #37809850
slippery
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, наследование
Blazkowicz,

да все таблицы джоинит, сказывается на производительности, при бизнес логике у меня в методе бывает, 7-8 таких запросов, смотрится страшно и тормозит, я не замерял по цифрам. получил здание избавится от таких запросов не переписывая бизнес-логику.
...
Рейтинг: 0 / 0
24.05.2012, 14:40
    #37809853
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, наследование
Вот оно, кажется:
https://hibernate.onjira.com/browse/ANN-103
...
Рейтинг: 0 / 0
24.05.2012, 14:41
    #37809856
IDVsbruck
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, наследование
Да, может, и не такие страшные эти затраты - столько джойнов делать.
Кстати, действительно, какие запросы генерит хибер в двух случаях:
1. session.get(ObjEntity.class, 1)
2. session.get(User.class, 1)
при стратегии наследования JOINED?
...
Рейтинг: 0 / 0
24.05.2012, 14:55
    #37809913
slippery
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, наследование
Blazkowicz,

что-то я не совсем понял, как у @SecondaryTable указать fetch="select"
...
Рейтинг: 0 / 0
24.05.2012, 14:58
    #37809918
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, наследование
slipperyчто-то я не совсем понял, как у @SecondaryTable указать fetch="select"
Какие ж все ленивые. Там тикет залинкован. В нем написано.
http://docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/annotations/Table.html
...
Рейтинг: 0 / 0
24.05.2012, 14:58
    #37809919
slippery
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, наследование
как я понял нельзя такое сделать.....хотя у меня в проекте хибернат 4.1 уже новее чем 3.2
...
Рейтинг: 0 / 0
24.05.2012, 15:01
    #37809932
slippery
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, наследование
slippery,

я просто javax подключал таблицы, не увидел ,сейчас проверю, отпишусь
...
Рейтинг: 0 / 0
24.05.2012, 15:34
    #37810036
slippery
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, наследование
Blazkowicz,

ОГРОМНОЕ СПАСИБО! Работает!!!))))
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
01.11.2014, 09:21
    #38793544
rema174
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, наследование
интересно, это нормально спрашивать на собес-и у джуниора о наследовании в хибернейт?
...
Рейтинг: 0 / 0
14.11.2014, 15:55
    #38806551
Victor Alenkov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Hibernate, наследование
rema174, если чел заявляет о знаниях Hibernate, то вполне нормально.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Hibernate, наследование / 24 сообщений из 24, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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