Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / абстрактный класс с полем другого абстрактного класса в Hibernate - реально? / 7 сообщений из 7, страница 1 из 1
27.08.2013, 20:57:42
    #38379256
gait
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
абстрактный класс с полем другого абстрактного класса в Hibernate - реально?
Есть класс AbstractTank с полем AbstractGun и классы SuperTank, UberTank, SuperGun, UberGun, которые экстендят соотвествующие абстрактные классы. И хибер ругается: org.hibernate.AnnotationException: @OneToOne or @ManyToOne on UberTank.gun references an unknown entity: AbstractGun

Вот такие у меня классы с маппингом:
Код: 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.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
@MappedSuperclass
public abstract class AbstractTank {
	
	public AbstractTank() {
	}
	
	private long id;
	
	@Id
	@GeneratedValue (strategy = GenerationType.SEQUENCE)
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	
	private String model;
	
	public String getModel() {
		return model;
	}
	
	public void setModel(String model) {
		this.model = model;
	}
	
	protected AbstractGun gun;
	
	@OneToOne
	public AbstractGun getGun() {
		return gun;
	}
	
	public void setGun(AbstractGun gun) {
		this.gun = gun;
	}
}

@MappedSuperclass
public class AbstractGun {
	
	public AbstractGun() {
	}
	
	@Id
	private long id;
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	
	private String model;
	
	public String getModel() {
		return model;
	}
	
	public void setModel(String model) {
		this.model = model;
	}
	
	private AbstractTank tank;
	
	@OneToOne
	public AbstractTank getTank() {
		return tank;
	}
	
	public void setTank(AbstractTank tank) {
		this.tank = tank;
	}
}

@Entity
@Table (name = "TEST_UBER_GUN")
	public class UberGun extends AbstractGun {
}

@Entity
@Table (name = "TEST_UBER_TANK")
	public class UberTank extends AbstractTank {
}

@Entity
@Table (name = "TEST_SUPER_TANK")
public class SuperTank extends AbstractTank {

}

@Entity
@Table (name = "TEST_SUPER_GUN")
public class SuperGun extends AbstractGun {

}



И вот тестовый пример:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
		AbstractTank tank = new SuperTank();
		tank.setModel("UBER MODEL");
		UberGun uberGun = new UberGun();
		uberGun.setModel("UBER GUN 221");
		uberGun.setTank(tank);
		tank.setGun(uberGun);
		
		sessionFactory = configureSessionFactory();
		Session session = sessionFactory.openSession();
		
		session.beginTransaction();
		session.save(uberGun);
		session.save(tank);
		session.getTransaction().commit();



Вообще не очень понятно, как хибер определит FK-еи для таблиц танков и пушек при таком подходе и как же тогда мне замапить такое? Откзаываться от абстрактного класса и копипастить код из него в конкретные классы и отказаться от полиморфизма?
...
Рейтинг: 0 / 0
28.08.2013, 01:26:49
    #38379409
Adva
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
абстрактный класс с полем другого абстрактного класса в Hibernate - реально?
gait,

ты уверен, что тебе нужно разносить все эти сущности по разным таблицам? На первый взгляд все оружие может лежать в одной таблице - guns, и танки - в одной таблице tanks с выборкой по дискриминатору, например. Если оставить как есть, то можно использовать generic и писать аннотацию @OneToOne не в абстрактном классе, а в потомке:

Код: 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.
@MappedSuperclass
public class AbstractGun<T> {
	
	// .....

	private T tank;
	
	public T getTank() {
		return tank;
	}
	
	public void setTank(T tank) {
		this.tank = tank;
	}
}

@Entity
@Table (name = "TEST_UBER_GUN")
	public class UberGun<UberTank> extends AbstractGun {

        @Override
        @OneToOne(targetEntity = UberTank.class)
        public UberTank getTank() {
		return super.getTank();
	}
}
...
Рейтинг: 0 / 0
28.08.2013, 01:29:29
    #38379410
Adva
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
абстрактный класс с полем другого абстрактного класса в Hibernate - реально?
точнее

Код: java
1.
2.
3.
// ...
public class UberGun extends AbstractGun<UberTank> {
// ...
...
Рейтинг: 0 / 0
28.08.2013, 11:17:14
    #38379641
gait
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
абстрактный класс с полем другого абстрактного класса в Hibernate - реально?
Чего-то не получается с генериками. Вываливается org.hibernate.MappingException: Could not determine type for: UberTank, at table: TEST_UBER_GUN, for columns: [org.hibernate.mapping.Column(tank)] :( Код такой:

AbstractTank.java:
Код: 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.
@MappedSuperclass
public abstract class AbstractTank<T> {
	
	public AbstractTank() {
	}
	
	private long id;
	
	@Id
	@GeneratedValue (strategy = GenerationType.SEQUENCE)
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	
	private String model;
	
	public String getModel() {
		return model;
	}
	
	public void setModel(String model) {
		this.model = model;
	}
	
	protected T gun;
	
	public T getGun() {
		return gun;
	}
	
	public void setGun(T gun) {
		this.gun = gun;
	}
}



UberTank.java
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
@Entity
@Table(name = "TEST_UBER_TANK")
public class UberTank extends AbstractTank<UberGun> {

	@Override
	@OneToOne(targetEntity = UberGun.class)
	public UberGun getGun() {
		return super.getGun();
	}
	
	@Override
	public void setGun(UberGun gun) {
		super.setGun(gun);
	}
}



AbstractGun.java
Код: 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.
@MappedSuperclass
public class AbstractGun<T> {

	public AbstractGun() {
	}

	private long id;

	@Id
	@GeneratedValue(strategy = GenerationType.SEQUENCE)
	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	private String model;

	public String getModel() {
		return model;
	}

	public void setModel(String model) {
		this.model = model;
	}

	private T tank;

	public T getTank() {
		return tank;
	}

	public void setTank(T tank) {
		this.tank = tank;
	}
}



UberGun.java
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
@Entity
@Table(name = "TEST_UBER_GUN")
public class UberGun extends AbstractGun<UberTank> {

	@Override
	@OneToOne(targetEntity = UberTank.class)
	public UberTank getTank() {
		return super.getTank();
	}
	
	@Override
	public void setTank(UberTank tank) {
		super.setTank(tank);
	}
}



Использование:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
		UberTank uberTank = new UberTank();
		uberTank.setModel("UBER MODEL T-34");
		UberGun uberGun = new UberGun();
		uberGun.setModel("UBER GUN 221");
		uberGun.setTank(uberTank);
		uberTank.setGun(uberGun);
		
		sessionFactory = configureSessionFactory();
		Session session = sessionFactory.openSession();
		
		session.beginTransaction();
		session.save(uberGun);
		session.save(uberTank);
		session.getTransaction().commit();



Еще я пробовал к вышеописанному добавить @AttributeOverride в UberGun и UberTank с оверрайдом поля "tank" и "gun" соотвественно, но это не помогло. Вообще я новичек в хибере, может я что-то упустил? Может нужно что-то еще добавить где-то?
...
Рейтинг: 0 / 0
28.08.2013, 11:44:23
    #38379683
gait
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
абстрактный класс с полем другого абстрактного класса в Hibernate - реально?
Advaты уверен, что тебе нужно разносить все эти сущности по разным таблицам? Было бы желательно, но если вариант с генериками не получится сделать, то буду делать как вы и описали - с двумя таблицами и дискриминатором.
...
Рейтинг: 0 / 0
28.08.2013, 13:20:18
    #38379801
Adva
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
абстрактный класс с полем другого абстрактного класса в Hibernate - реально?
gait,

в абстрактном классе надо было пометить методы getTank() и getGun() аннотацией @Transient. Во вложении рабочий код.
...
Рейтинг: 0 / 0
31.08.2013, 14:52:19
    #38383155
gait
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
абстрактный класс с полем другого абстрактного класса в Hibernate - реально?
Спасибо, Adva! С @Transient на геттере всё заработало! Но воспользоваться полиморфизмом в полной мере (то есть когда мы любому абстрактному танку можем просетать любую абстрактную пушку. То есть убер танку можно просетать супер пушку итп) получается только используя первый вариант (одна таблица с дискриминатором) и я немного подумав понял, что всё-таки перемудрил с разбиением, нужно было одной таблицей делать с самого начала. Еще раз спасибо!
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / абстрактный класс с полем другого абстрактного класса в Hibernate - реально? / 7 сообщений из 7, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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