Question

J'ai une table qui a deux clés étrangères à deux tables différentes avec les clés étrangères partager une colonne :

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)
)

Comme vous pouvez le voir, il y a deux FKs partage country_code (référencement par hasard la même colonne à la fin du chemin de référenciation). Les regards de la classe d'entités comme (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;

    ...
}

Comme vous pouvez le voir, je signale la propriété countryCode et country_code de la ville de @JoinColumn en lecture seule (insérable = false, actualisable = false). Mise en veille prolongée échoue avec ce disant:

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

Cela me semble assez basique honnêtement. « Le mélange des colonnes insérables et insérables dans une propriété n'est pas autorisée » est une si faible « excuse », est-il pas?

Hibernate doit être capable de gérer cela, par exemple selon la spécification JPA? Est-ce un bug?

Était-ce utile?

La solution 2

sera pris en charge avec Hibernate 5, voir https://hibernate.atlassian.net/browse / HHH-6221

Autres conseils

Il existe un moyen de contourner la validation et l'obtenir au travail, indiquant ainsi la colonne est un « @JoinColumnsOrFormulas », puis mettre la solution:

Erreur:

@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;

OK:

@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;

Cordialement,

J'utilise veille prolongée 5 et je reçois encore cette exception. Si vous ajoutez insert = « false », mise à jour = « false » à un seul, vous obtiendrez une exception indiquant que vous mixtes colonnes insérables et non insérables et que ce n'est pas autorisé. Ceci est une question qui est déjà dans le système de suivi, mais ne semble pas être résolu. Mise en veille prolongée lancers francs sur la colonne AnnotationException utilisée par plusieurs clés étrangères se chevauchent

Dans notre cas, cela signifie que nous avons migré vers EclipseLink, qui est en fait assez facile étant donné que vous avez besoin principalement de remplacer le persistence.xml et réécrire le HSQL (Hibernate SQL) à JPQL (JPA SQL). Aussi, vous devrez peut-être remplacer les stratégies de nommage personnalisées (Eclipse les appelle SessionCustomizer). Bien sûr, il pourrait être plus difficile à faire si vous utilisez des fonctions spéciales de mise en veille prolongée, comme mise en veille prolongée chercher, etc. Mais dans notre cas, nous avons essayé de fixer chevauchement des clés étrangères pendant des semaines quand la migration n'a pris des heures à la fin.

Ceci est toujours pas résolu dans Hibernate 5. Cependant, si j'utilise @JoinColumnsOrFormulas je reçois ClassCastException. insertable = false, updatable = false sur toutes les ajoutant colonnes de jointure a résolu mon problème:

Exemple:

@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;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top