Mam tabeli, które ma dwa klucze obce do dwóch różnych tabel z obu kluczy obcych dzieląc jedną kolumnę:Czy funkcja Hibernate powinna obsługiwać nakładające się klucze obce?
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)
)
Jak widać, istnieją dwa FKS dzielące COUNTRY_CODE (przypadkowo przedstawieniu tej samej kolumny w koniec ścieżki referencyjnej). Klasa podmiot wygląda (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;
...
}
Jak widać ja oflagowany właściwość CountryCode i kod_kraju @JoinColumn miasta jako tylko do odczytu (do wkładania = false, aktualizowalny = false). Hibernacja kończy się niepowodzeniem z następującym powiedzeniem:
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
Wygląda to całkiem podstawowo dla mnie szczerze. "Mieszanie kolumn, które można wstawiać i których nie można wstawiać w nieruchomości jest niedozwolone" jest tak słabym "wymówką", nieprawdaż?
Czy Hibernate może sobie z tym poradzić, np. zgodnie ze specyfikacją JPA? Czy to błąd?
Oto JavaSE, HSQLDB, Ant aplikacja samodzielna: http://www.kawoolutions.com/media/geoinfo-hib-overlapping -fks.zip – Kawu
Hibernacja nie podoba się kluczom pierwotnym złożonym - w niektórych sytuacjach, takich jak ten, zawodzi. spróbuj zmienić swoją bazę danych, aby używać podstawowych kluczy z jedną kolumną. –
Tak Hibernacja zasysa klucze złożone. W każdym razie nie zostało to zgłoszone, teraz jest: http: //opensource.atlassian.com/projects/hibernate/browse/HHH-6221 – Kawu