powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / абстрактный класс с полем другого абстрактного класса в Hibernate - реально?
7 сообщений из 7, страница 1 из 1
абстрактный класс с полем другого абстрактного класса в Hibernate - реально?
    #38379256
gait
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть класс 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
абстрактный класс с полем другого абстрактного класса в Hibernate - реально?
    #38379409
Adva
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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
абстрактный класс с полем другого абстрактного класса в Hibernate - реально?
    #38379410
Adva
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
точнее

Код: java
1.
2.
3.
// ...
public class UberGun extends AbstractGun<UberTank> {
// ...
...
Рейтинг: 0 / 0
абстрактный класс с полем другого абстрактного класса в Hibernate - реально?
    #38379641
gait
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Чего-то не получается с генериками. Вываливается 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
абстрактный класс с полем другого абстрактного класса в Hibernate - реально?
    #38379683
gait
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Advaты уверен, что тебе нужно разносить все эти сущности по разным таблицам? Было бы желательно, но если вариант с генериками не получится сделать, то буду делать как вы и описали - с двумя таблицами и дискриминатором.
...
Рейтинг: 0 / 0
абстрактный класс с полем другого абстрактного класса в Hibernate - реально?
    #38379801
Adva
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
gait,

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


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