Должен ли стремиться к гибернации обращаться с перекрывающимися иностранными ключами?
-
26-09-2019 - |
Вопрос
У меня есть таблица, которая имеет два иностранных ключей до двух разных таблиц с обоими зарубежными ключами Распределение одного столбца:
CREATE TABLE ZipAreas
(
country_code CHAR(2) NOT NULL,
zip_code VARCHAR(10) NOT NULL,
state_code VARCHAR(5) NOT NULL,
city_name VARCHAR(100) NOT NULL,
PRIMARY KEY (country_code, zip_code, state_code, city_name),
FOREIGN KEY (country_code, zip_code) REFERENCES Zips (country_code, code),
FOREIGN KEY (country_code, state_code, city_name) REFERENCES Cities (country_code, state_code, name)
)
Как видите, существует два FKS Countrying Country_Code (совпадает с ссылкой на тот же столбец в конце пути референции). Класс Entity выглядит (JPA 1.0 @IDClass):
@Entity
@Table(name = "ZipAreas")
@IdClass(value = ZipAreaId.class)
public class ZipArea implements Serializable
{
@Id
@Column(name = "country_code", insertable = false, updatable = false)
private String countryCode;
@Id
@Column(name = "zip_code", insertable = false, updatable = false)
private String zipCode;
@Id
@Column(name = "state_code", insertable = false, updatable = false)
private String stateCode;
@Id
@Column(name = "city_name", insertable = false, updatable = false)
private String cityName;
@ManyToOne
@JoinColumns(value = {@JoinColumn(name = "country_code", referencedColumnName = "country_code"), @JoinColumn(name = "zip_code", referencedColumnName = "code")})
private Zip zip = null;
@ManyToOne
@JoinColumns(value = {@JoinColumn(name = "country_code", referencedColumnName = "country_code", insertable = false, updatable = false), @JoinColumn(name = "state_code", referencedColumnName = "state_code"), @JoinColumn(name = "city_name", referencedColumnName = "name")})
private City city = null;
...
}
Как вы можете видеть, я пометил свойство CountryCode и Country_Code Country_Code @joinnumn в качестве только для чтения (вставляется = false, Updatable = false). Hibernate не удается с этим поговорка:
Exception in thread "main" javax.persistence.PersistenceException: [PersistenceUnit: geoinfo] Unable to configure EntityManagerFactory
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:374)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:56)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:48)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:32)
at tld.geoinfo.Main.main(Main.java:27)
Caused by: org.hibernate.AnnotationException: Mixing insertable and non insertable columns in a property is not allowed: tld.geoinfo.model.ZipAreacity
at org.hibernate.cfg.Ejb3Column.checkPropertyConsistency(Ejb3Column.java:563)
at org.hibernate.cfg.AnnotationBinder.bindManyToOne(AnnotationBinder.java:2703)
at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:1600)
at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:796)
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:707)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3977)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3931)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1368)
at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1345)
at org.hibernate.ejb.Ejb3Configuration.buildMappings(Ejb3Configuration.java:1477)
at org.hibernate.ejb.EventListenerConfigurator.configure(EventListenerConfigurator.java:193)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:1096)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:278)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:362)
... 4 more
Это выглядит довольно хорошо для меня честно. «Смешивание вставимых и не вставленных колоннах в недвижимости не допускается» - это такое слабое «оправдание», не так ли?
Должен ли стремиться к гибернации справиться с этим, например, в соответствии с спецификацией JPA? Это ошибка?
Решение 2
Будет поддерживаться с помощью Hibernate 5, см. https://hibernate.atlassian.net/browse/hhhh-6221.
Другие советы
Есть способ обойти проверку и получить его на работу, что указывает на то, что указывает на столбец - «@joinColumnsOrmpranculs», а затем поставить решение:
Ошибка:
@ManyToOne
@JoinColumns(value = {
@JoinColumn(name = "country_code", referencedColumnName = "country_code"),
@JoinColumn(name = "zip_code", referencedColumnName = "code")})
private Zip zip = null;
@ManyToOne
@JoinColumns(value = {
@JoinColumn(name = "country_code", referencedColumnName = "country_code", insertable = false, updatable = false),
@JoinColumn(name = "state_code", referencedColumnName = "state_code"),
@JoinColumn(name = "city_name", referencedColumnName = "name")})
private City city = null;
ХОРОШО:
@ManyToOne
@JoinColumns(value = {
@JoinColumn(name = "country_code", referencedColumnName = "country_code"),
@JoinColumn(name = "zip_code", referencedColumnName = "code")})
private Zip zip = null;
@ManyToOne
@JoinColumnsOrFormulas(value = {
@JoinColumnOrFormula(formula = @JoinFormula(value = "country_code", referencedColumnName = "country_code")),
@JoinColumnOrFormula(column = @JoinColumn(name = "state_code", referencedColumnName = "state_code")),
@JoinColumnOrFormula(column = @JoinColumn(name = "city_name", referencedColumnName = "name"))
})
private City city = null;
С уважением,
Я использую Hibernate 5, и я все еще получаю это исключением. Если вы добавите вставку = «false», обновите = "false" только на один, вы получите исключение, указав, что вы смешанные вставляемые и не вставляемые столбцы, и что это не допускается. Это проблема, которая уже находится в трекере, но, кажется, не решается. Hibernate бросает AnnotationException на столбец, используемой несколькими перекрывающимися внешними клавишами
В нашем случае это означало, что мы мигрировали в EclipseLink, что на самом деле довольно легко придано, что вам в основном нужно заменить настойчивость .xml и переписать HSQL (Hibernate SQL) к JPQL (JPA SQL). Также вам могут потребоваться заменить пользовательские стратегии именования (Eclipse вызывает их SessionCustomizer). Конечно, может быть сложнее сделать, если вы используете особые функции Hibernate, таких как поиск в гибернации и т. Д. Но в нашем случае мы попытались исправить перекрывающиеся внешние ключи в течение нескольких недель, когда миграция заняла только часы в конце.
Это все еще не решено в Hibernate 5. Однако, если я использую @JoinColumnsOrFormulas
Я получаю ClassCastexception. Приплыв insertable = false, updatable = false
На всех объединяях столбцы решили мою проблему:
Пример:
@ManyToOne
@JoinColumns(value = {
@JoinColumn(name = "country_code", referencedColumnName = "country_code", insertable = false, updatable = false),
@JoinColumn(name = "state_code", referencedColumnName = "state_code", insertable = false, updatable = false),
@JoinColumn(name = "city_name", referencedColumnName = "name", insertable = false, updatable = false)})
private City city = null;