我有一个表,该表具有指向两个不同表的两个外键,两个外键 共享一个列 :
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) )
如您所见,有两个FK共享country_code(恰好在引用路径的末尾引用同一列)。实体类看起来像(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 @JoinColumn标记为只读(insertable = false,可更新= 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
老实说,这对我来说很基本。“不允许在属性中混合可插入和不可插入的列”是一个很弱的“借口”,不是吗?
Hibernate是否应该能够按照JPA规范进行处理?这是错误吗?
Hibernate 5将支持,请参阅https://hibernate.atlassian.net/browse/HHH-6221