Hibernate запрещает только чтение для @Column во встроенных классах составных первичных ключей ID (ошибка?)? - PullRequest
1 голос
/ 22 ноября 2010

Вот дизайн БД (DDL):

CREATE TABLE Countries
(
  iso_code CHAR(2) NOT NULL,
  name VARCHAR(50) NOT NULL,
  PRIMARY KEY (iso_code)
);

CREATE TABLE Zips
(
  country_code CHAR(2) NOT NULL,
  code VARCHAR(10) NOT NULL,
  PRIMARY KEY (country_code, code),
  FOREIGN KEY (country_code) REFERENCES Countries (iso_code)
);

Вот класс Zip + класс составного первичного ключа:

@Entity
@Table(name = "Zips")
public class Zip implements Serializable
{
    @EmbeddedId
    private ZipId embeddedId;

    @ManyToOne
    @JoinColumn(name = "country_code", referencedColumnName = "iso_code")
    private Country country = null;

    ...
}

@Embeddable
public class ZipId implements Serializable
{
    @Column(name = "country_code", insertable = false, updatable = false)
    private String countryCode;

    @Column(name = "code")
    private String code;

    ...
}

Трассировка стека в спящем режиме:

Exception in thread "main" javax.persistence.PersistenceException: [PersistenceUnit: zips] Unable to build EntityManagerFactory
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:911)
    at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:57)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:48)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:32)
    at tld.zips.Main.main(Main.java:27)
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: tld.zips.model.Zip column: country_code (should be mapped with insert="false" update="false")
    at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:675)
    at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:697)
    at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:719)
    at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:473)
    at org.hibernate.mapping.RootClass.validate(RootClass.java:235)
    at org.hibernate.cfg.Configuration.validate(Configuration.java:1332)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1835)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:902)
    ... 4 more

Что это? код страны отображается как доступный только для чтения (вставляемый = ложь, обновляемый = ложный) в классе составного первичного ключа. Это отлично работает с EclipseLink! Классы IIRC @Embeddable допускают @Basic, @Column, @Enumerated, @Temporal, @Lob и @Embedded на свои столбцы, поэтому это должно работать. Обратите внимание, что код совместим с JPA 1.0.

Исключение исчезает при добавлении вставляемого = false, updatable = false в @JoinColumn, но это не то, что я хочу. Я предпочитаю, чтобы мои ассоциации были доступны для записи ...

Это ошибка Hibernate? Я использую стабильную версию Hibernate 3.6.

Ответы [ 2 ]

0 голосов
/ 22 ноября 2010

Похоже, ошибка. В качестве обходного пути вы можете поместить country в ZipId вместо countryCode:

@Entity 
@Table(name = "Zips") 
public class Zip implements Serializable 
{ 
    @EmbeddedId 
    private ZipId embeddedId;  
    ... 
} 

@Embeddable 
public class ZipId implements Serializable 
{ 
    @ManyToOne 
    @JoinColumn(name = "country_code", referencedColumnName = "iso_code") 
    private Country country = null; 

    @Column(name = "code") 
    private String code; 

    ... 
} 
0 голосов
/ 22 ноября 2010

Да, похоже на ошибку.Во всяком случае, вы можете сделать это так, я полагаю.Хотя сам не пробовал.

@Entity
@Table(name = "Zips")
public class Zip implements Serializable
{
    @EmbeddedId
    @AttributeOverrides({
        @AttributeOverride(name="countryCode", column=@Column(name="country_code", insertable = false, updatable = false))
        @AttributeOverride(name="code", column=@Column("code"))
    })
    private ZipId embeddedId;

    @ManyToOne
    @JoinColumn(name = "country_code", referencedColumnName = "iso_code")
    private Country country;

    ...
}

@Embeddable
public class ZipId implements Serializable
{
    private String countryCode;
    private String code;    

    ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...