powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Составной ИД в ентити, ребус, крохсворд, загадка природы
10 сообщений из 10, страница 1 из 1
Составной ИД в ентити, ребус, крохсворд, загадка природы
    #37736121
AndreyDmt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Приветсвую!
Вчера к концу дня заимел заморочку, думал дело житейское -
конец понедельника. Ан нет, не рассосалось.
Голову сломал, явно мой глюк, но найти не могу, спасайте!
(Все исходные в конце приведу - пока плач Ярославны)
Суть беды: периодически возникает необходимость в Entity
описывать составной первичный ключ. Не злоупотребляю, но бывает.
В проекте штуки 3-4 есть таких, проблем не доставляют, всё работает.
Вчера затеял изменение, в том числе поменял в одном из ентити простой
ключ на составной. МетОда под копирку, кнтрл Ц - кнтрл В.
Компилю, деплою - на правленном ентити выскакивает ошибка от
хибернейта: пропущена колонка. Смотрю, чешу репу. А с чего ей
быть - оно же через @Transient описано. Комментирую, деплою, результат -
не находится следующее поле, по алфавиту как оказалось(уже реальное).
Причём не находит имя не то, что в @Column(name="") указано,
а имя поля класса (ну не совпадают они у меня). Меняю поле в классе
на то, как оно пишется в таблице - признаёт. Но ругань на следующее поле.
Причём для меня стало открытием, что хибернейту (или кому?) по барабану
на геттеры-сеттеры: он явно проверяет приват поле (как?) и на него
рурается, или признаёт. Ибо я имя полю поменял, а геттеры-сеттеры остались
прежние, забылся. Так ить сработало! Ушла ошибка дальше. Так и должно быть?
Вобщем вывод сделал следующий: в отдельно взятом ентити перестали
работать (опознаваться) аннотации. Понял, что бред, пошёл бороться дальше.
Начал сравнивать побайтно тексты классов, которые работают, и сломанного -
отличий не нашёл. Перечитал туториал по j2ee5 - вроде всё правильно у меня,
всё по буквам. Создал новую тестовую табличку, с нуля написал ентити,
класс составного ключа - ошибка. Но блин, соседние ентити ж работают!
Смотрю по списку в логах - нормално их хбернейт проходит, не жалуется.
Вообщем или мозги в отгуле, или глаз замылился. Поспособствуйте прозрению плиз!

Театр действий:
windowsXP
jdk-1.6.31
Jboss-5.1, seam-2.2.2
Eclipse 3.7.2 + JbossTools 3.3
БД - Oracle10.2
Исходники по тестовой таблице, классам:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
CREATE TABLE A$_CONTEXTDATA (
  APPLICATION_ID     NUMBER(20)                 NOT NULL,
  CONTEXTCLASS_NAME  VARCHAR2(100 CHAR)         NOT NULL,
  HELP_CONTEXT       VARCHAR2(200 CHAR)
);

CREATE UNIQUE INDEX A$_CONTEXTDATA_PK ON A$_CONTEXTDATA
(APPLICATION_ID, CONTEXTCLASS_NAME);

ALTER TABLE A$_CONTEXTDATA ADD (
  CONSTRAINT A$_CONTEXTDATA_PK
 PRIMARY KEY
 (APPLICATION_ID, CONTEXTCLASS_NAME));


Первичный ключ:
Код: 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.
package org.kronacommon.app.entity;

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Embeddable;

@Embeddable
public final class AaaContextDataKey implements Serializable {

	private static final long serialVersionUID = 1493537710517406682L;

	public AaaContextDataKey() {
	}

	// На это ругается, если поменять на application_id, не меняя
	// get - set, то поле считается правильно оформленным
	private Long appId;

	@Column(name = "APPLICATION_ID")
	public Long getAppId() {
		return this.appId;
	}

	public void setAppId(Long appId) {
		this.appId = appId;
	}

	private String contCN;

	@Column(name = "CONTEXTCLASS_NAME")
	public String getContCN() {
		return this.contCN;
	}

	public void setContCN(String contCN) {
		this.contCN = contCN;
	}

	@Override
	public boolean equals(Object otherKey) {
		if (this == otherKey) return true;
		if (otherKey == null) return false;
		if (!(otherKey instanceof AaaContextDataKey)) return false;
		AaaContextDataKey other = (AaaContextDataKey) otherKey;
		if ((this.appId == null) & (other.appId != null)) return false;
		if ((this.appId != null) & (other.appId == null)) return false;
		if ((this.contCN == null) & (other.contCN != null)) return false;
		if ((this.contCN != null) & (other.contCN == null)) return false;
		if ((this.appId == null) & (other.appId == null) & (this.contCN == null)
				& (other.contCN == null)) return true;
		if ((this.appId.equals(other.appId)) && (this.contCN.equals(other.contCN))) return true;
		return false;
	}

	@Override
	public int hashCode() {
		return ((this.appId == null ? 0 : this.appId.hashCode()) ^ (this.contCN == null ? 0
				: this.contCN.hashCode()));
	}

	@Override
	public String toString() {
		return "" + this.appId.toString() + "." + this.contCN;
	}
}


Сам ентити:
Код: 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.
package org.kronacommon.app.entity;

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;

@Entity
@Table(name = "A$_CONTEXTDATA")
public class AaaContextDataEntity implements Serializable {

	private static final long serialVersionUID = 8244148633373180589L;

	public AaaContextDataEntity() {

	}

	//
	@EmbeddedId
	private AaaContextDataKey contextDataKey;

	public AaaContextDataKey getContextDataKey() {
		return this.contextDataKey;
	}

	public void setContextDataKey(AaaContextDataKey contextDataKey) {
		this.contextDataKey = contextDataKey;
	}
	
	// Правлю поля в классе первичного ключа, ругань перекидывается сюда
	private String helpContext;

	@Column(name = "HELP_CONTEXT", length = 200, unique = false, nullable = true)
	public String getHelpContext() {
		return this.helpContext;
	}

	public void setHelpContext(String helpcontext) {
		this.helpContext = helpcontext;
	}
}


Сообщение об ошибке:
Код: 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.
2012-04-03 14:01:01,984 INFO  [org.hibernate.tool.hbm2ddl.TableMetadata] (HDScanner) table found: KRONAV2.A$_CONTEXTDATA
2012-04-03 14:01:01,984 INFO  [org.hibernate.tool.hbm2ddl.TableMetadata] (HDScanner) columns: [help_context, contextclass_name, application_id]
2012-04-03 14:01:01,984 ERROR [org.jboss.kernel.plugins.dependency.AbstractKernelController] (HDScanner) Error installing to Start: name=persistence.unit:unitName=kronav2mear.ear/#kronav2meta state=Create
javax.persistence.PersistenceException: [PersistenceUnit: kronav2meta] Unable to build EntityManagerFactory
....
Caused by: org.hibernate.HibernateException: Missing column: appId in KRONAV2.A$_CONTEXTDATA
	at org.hibernate.mapping.Table.validateColumns(Table.java:277)
	at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1116)
	at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:139)
	at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:349)
	at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1327)
	at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867)
	at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:669)
	... 56 more
И как резюм в конце деплоя:

DEPLOYMENTS IN ERROR:
  Deployment "persistence.unit:unitName=kronav2ear.ear/#kronav2" is in error due to the following reason(s):
		org.hibernate.HibernateException: Missing column: appId in KRONAV2.A$_CONTEXTDATA
	at org.jboss.deployers.plugins.deployers.DeployersImpl.checkComplete(DeployersImpl.java:993)
	at org.jboss.deployers.plugins.deployers.DeployersImpl.checkComplete(DeployersImpl.java:939)
	at org.jboss.deployers.plugins.main.MainDeployerImpl.checkComplete(MainDeployerImpl.java:873)
	at org.jboss.system.server.profileservice.repository.MainDeployerAdapter.checkComplete(MainDeployerAdapter.java:128)
	at org.jboss.system.server.profileservice.hotdeploy.HDScanner.scan(HDScanner.java:369)
	at org.jboss.system.server.profileservice.hotdeploy.HDScanner.run(HDScanner.java:255)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
	at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317)
	at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:180)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:204)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:662)
}


Ну и понятно, что если убрать составной ключ (т.е. сделать через @Id на скажем appId,
ну и в таблице поправить, то всё нормально работает)
...
Рейтинг: 0 / 0
Составной ИД в ентити, ребус, крохсворд, загадка природы
    #37736152
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndreyDmt,
не делай составные.
Выгоды мало и тебе, и серверу.
...
Рейтинг: 0 / 0
Составной ИД в ентити, ребус, крохсворд, загадка природы
    #37736196
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Возможно что @Column вообще игнорируется в Embeddable. Потому что ключ должен использоваться в разных таблицах.
У нас сделано через AttributeOverrides
http://stackoverflow.com/questions/331744/jpa-multiple-embedded-fields
http://stackoverflow.com/questions/3046677/automatically-add-a-prefix-to-column-names-for-embeddable-classes
http://stackoverflow.com/questions/951372/hibernate-mapping-a-second-embeddable-field-in-a-subclass
...
Рейтинг: 0 / 0
Составной ИД в ентити, ребус, крохсворд, загадка природы
    #37736513
AndreyDmt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ну вообще я очень осторожно составные ключи пользую. Но вот понадобилось.
Меня напрягает, что в том же пакете практически идентичный комплект Первичный ключ-Ентити работал и работает
без проблем, я даже отличий не нахожу, кроме нюансов.
И аннотации там работают. А в дефектном не работают как в классе первичного ключа, так и в самом ентити.
Более того не работает не только @Column, но @Transient - то есть ничего :-))
...
Рейтинг: 0 / 0
Составной ИД в ентити, ребус, крохсворд, загадка природы
    #37736531
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndreyDmtБолее того не работает не только @Column, но @Transient - то есть ничего :-))

Может из-за final ?
...
Рейтинг: 0 / 0
Составной ИД в ентити, ребус, крохсворд, загадка природы
    #37736544
AndreyDmt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczAndreyDmtБолее того не работает не только @Column, но @Transient - то есть ничего :-))

Может из-за final ?

final сперва и не было. В туториал залез, там почему то с final пример. Поставил, ничего не поменялось
...
Рейтинг: 0 / 0
Составной ИД в ентити, ребус, крохсворд, загадка природы
    #37736556
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Остаётся подебажить.
...
Рейтинг: 0 / 0
Составной ИД в ентити, ребус, крохсворд, загадка природы
    #37736603
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndreyDmtНу вообще я очень осторожно составные ключи пользую. Но вот понадобилось.AndreyDmt,
я делал по началу составные ключи.... Что называется - экономил. Но потом, при добавлении связей и таблиц JOIN всё равно приходилось вводить суррогатные.
Напр. - каскад из Город-Район-Улица и т.д.
...
Рейтинг: 0 / 0
Составной ИД в ентити, ребус, крохсворд, загадка природы
    #37736608
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123я делал по началу составные ключи.... Что называется - экономил. Но потом, при добавлении связей и таблиц JOIN всё равно приходилось вводить суррогатные.
Напр. - каскад из Город-Район-Улица и т.д.
+1
...
Рейтинг: 0 / 0
Составной ИД в ентити, ребус, крохсворд, загадка природы
    #37736640
AndreyDmt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ну блин, оконфузился! Аж краска прошибает. Почувствуйте разницу:
Не работает
//
@EmbeddedId
private AaaContextDataKey contextDataKey;

public AaaContextDataKey getContextDataKey() {
return this.contextDataKey;
}

public void setContextDataKey(AaaContextDataKey contextDataKey) {
this.contextDataKey = contextDataKey;
}
Работает
//
private AaaContextDataKey contextDataKey;

@EmbeddedId
public AaaContextDataKey getContextDataKey() {
return this.contextDataKey;
}

public void setContextDataKey(AaaContextDataKey contextDataKey) {
this.contextDataKey = contextDataKey;
}
Тыща извинений за количество букв, при мизере проблем.
Точно понедельник виноват...
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Составной ИД в ентити, ребус, крохсворд, загадка природы
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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