Malgré tous les autres articles, je ne trouve pas de solution à cette erreur avec GlassFish, sous MacOSX, NetBeans 7.2.
Here the error :
SEVERE: Exception while invoking class org.glassfish.persistence.jpa.JPADeployer
prepare method
SEVERE: Exception while preparing the app
SEVERE: [PersistenceUnit: supmarket] Unable to build EntityManagerFactory
...
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity:
com.supmarket.entity.Sale column: customerId
(should be mapped with insert="false" update="false")
Voici le code:
Sale.Java
@Entity
public class Sale {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable=false)
private Long idFromAgency;
private float amountSold;
private String agency;
@Temporal(javax.persistence.TemporalType.DATE)
private Date createdate;
@Column(nullable=false)
private Long productId;
@Column(nullable=false)
private Long customerId;
@ManyToOne(optional=false)
@JoinColumn(name="productId",referencedColumnName="id_product")
private Product product;
@ManyToOne(optional=false)
@JoinColumn(name="customerId",referencedColumnName="id_customer")
private Customer customer;
public void Sale(){}
public void Sale(Long idFromAgency, float amountSold, String agency
, Date createDate, Long productId, Long customerId){
...
}
// then getters/setters
}
Client.Java
@Entity
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="id_customer")
private Long id_customer;
@Column(nullable=false)
private Long idFromAgency;
private String gender,
maritalState,
firstname,
lastname,
incomeLevel;
@OneToMany(mappedBy="customer",targetEntity=Sale.class, fetch=FetchType.EAGER)
private Collection sales;
public void Customer(){}
public void Customer(Long idFromAgency, String gender, String maritalState,
String firstname, String lastname, String incomeLevel) {
...
}
}
Product.Java
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="id_product")
private Long id_product;
@Column(nullable=false)
private Long idFromAgency;
private String name;
@OneToMany(mappedBy="product",targetEntity=Sale.class, fetch=FetchType.EAGER)
private Collection sales;
//constructors + getters +setters
}
Le message est clair: vous avez une colonne répétée dans le mappage. Cela signifie que vous avez mappé deux fois la même colonne de base de données. Et en effet, vous avez:
@Column(nullable=false)
private Long customerId;
et aussi:
@ManyToOne(optional=false)
@JoinColumn(name="customerId",referencedColumnName="id_customer")
private Customer customer;
(et il en va de même pour productId
/product
).
Vous ne devez pas référencer d'autres entités par leur ID, mais par une référence directe à l'entité. Supprimez le champ customerId
, c'est inutile. Et faites de même pour productId
. Si vous voulez l'identifiant client d'une vente, il vous suffit de faire ceci:
sale.getCustomer().getId()
Si vous êtes coincé avec une base de données héritée sur laquelle quelqu'un avait déjà placé des annotations JPA mais ne définissait PAS les relations et que vous essayez maintenant de définir pour les utiliser dans votre code, il se peut que vous ne puissiez PAS supprimer customerId @Column car un autre code. peut directement le référencer déjà. Dans ce cas, définissez les relations comme suit:
@ManyToOne(optional=false)
@JoinColumn(name="productId",referencedColumnName="id_product", insertable=false, updatable=false)
private Product product;
@ManyToOne(optional=false)
@JoinColumn(name="customerId",referencedColumnName="id_customer", insertable=false, updatable=false)
private Customer customer;
Cela vous permet d'accéder aux relations. Cependant, pour ajouter/mettre à jour les relations, vous devrez manipuler les clés étrangères directement via leurs valeurs @Column définies. Ce n'est pas une situation idéale, mais si vous rencontrez ce genre de situation, vous pouvez au moins définir les relations afin que vous puissiez utiliser JPQL avec succès.
utilisez ceci, c'est du travail pour moi:
@Column(name = "candidate_id", nullable=false)
private Long candidate_id;
@ManyToOne(optional=false)
@JoinColumn(name = "candidate_id", insertable=false, updatable=false)
private Candidate candidate;
@Id
@Column(name = "COLUMN_NAME", nullable = false)
public Long getId() {
return id;
}
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, targetEntity = SomeCustomEntity.class)
@JoinColumn(name = "COLUMN_NAME", referencedColumnName = "COLUMN_NAME", nullable = false, updatable = false, insertable = false)
@org.hibernate.annotations.Cascade(value = org.hibernate.annotations.CascadeType.ALL)
public List<SomeCustomEntity> getAbschreibareAustattungen() {
return abschreibareAustattungen;
}
Si vous avez déjà mappé une colonne et que vous avez accidentellement défini les mêmes valeurs pour nom et referenceColumnName dans @ JoinColumn hibernate génère la même erreur stupide.
Erreur:
Causée par: org.hibernate.MappingException: colonne répétée dans le mappage pour l'entité: com.testtest.SomeCustomEntity colonne: COLUMN_NAME (doit être mappé avec insert = "false" update = "false")
Veillez à ne fournir qu'un seul setter et getter pour chaque attribut. La meilleure façon de procéder consiste à rédiger la définition de tous les attributs, puis à utiliser Eclipse generate, un utilitaire de définition et d'acquisition, plutôt que de le faire manuellement. L'option est disponible avec un clic droit -> source -> Générer Getter et Setter.