128

Despite all of the others post, I can't find a solution for this error with GlassFish, on 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")

Here the 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
}

Customer.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
}
Elrond_EGLDer
  • 47,430
  • 25
  • 189
  • 180
canardman
  • 2,773
  • 6
  • 24
  • 27

8 Answers8

152

The message is clear: you have a repeated column in the mapping. That means you mapped the same database column twice. And indeed, you have:

@Column(nullable=false)
private Long customerId;

and also:

@ManyToOne(optional=false)
@JoinColumn(name="customerId",referencedColumnName="id_customer")
private Customer customer;

(and the same goes for productId/product).

You shouldn't reference other entities by their ID, but by a direct reference to the entity. Remove the customerId field, it's useless. And do the same for productId. If you want the customer ID of a sale, you just need to do this:

sale.getCustomer().getId()
JB Nizet
  • 633,450
  • 80
  • 1,108
  • 1,174
  • 1
    I get the same error, but my situation is a bit different. My entity can be the father of one or more entities of the same type. The children have a reference on the id of their father as well as a unique id of their own. How can I resolve such a circular dependency? – Ciri Jan 22 '15 at 11:40
  • @JBNizet How then can I *save* a Sale with some particular `customerId`? (e.g. from JSON). – Mikhail Batcer Nov 05 '15 at 07:16
  • 2
    `Customer customer = entityManager.getReference(customerId, Customer.class); sale.setCustomer(customer);` – JB Nizet Nov 05 '15 at 07:18
  • Wouldn't that do an extra fetch from the DB to get the Customer object just to get it's id, which you already have since you're using it to look up the Customer?? – sockmonk Apr 13 '16 at 18:27
  • once you remove customerId, can you still do findByCustomeId(Long customeId) ? – Tiina Feb 13 '17 at 09:00
  • 8
    How do you handle the case where you have a `@EmbeddedId` composite key between `customerId` and another field of the `Customer` class? In this case I need both repeated column in the mapping, am i right? – louis amoros Apr 10 '17 at 09:55
  • 2
    @louisamoros Yes, you repeat it, but you add `@MapsId("customerId")`, see https://stackoverflow.com/questions/16775055/hibernate-embeddedid-join – Dalibor Filus Nov 23 '17 at 17:22
  • @Ciri, you have to remove from entity a column which is mapped to the same table’s primary key. See here more details https://www.viralpatel.net/hibernate-self-join-annotations-one-to-many-mapping/ – Denis Orlov Feb 05 '20 at 07:41
  • @JBNizet using `sale.getCustomer().getId()` would trigger a join for Customer table? when using LAZY loading? – Anan Raddad Apr 22 '20 at 12:45
78

If you are stuck with a legacy database where someone already placed JPA annotations on but did NOT define the relationships and you are now trying to define them for use in your code, then you might NOT be able to delete the customerId @Column since other code may directly reference it already. In that case, define the relationships as follows:

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

This allows you to access the relationships. However, to add/update to the relationships you will have to manipulate the foreign keys directly via their defined @Column values. It's not an ideal situation, but if you are handed this sort of situation, at least you can define the relationships so that you can use JPQL successfully.

PerkOne
  • 43
  • 1
  • 6
pattmatt
  • 801
  • 6
  • 3
  • 1
    Thanks, this is exactly the solution I need, besides the `ManyToOne` mapping field, I need a field directly mapped to the join column. – ryenus Aug 15 '14 at 03:20
  • This is the right solution when you have a field that is foreing key and primary key at the same time. – AntuanSoft Oct 06 '17 at 11:57
  • Oh my god, you might have saved my day... exactly this case – Clomez Jun 05 '19 at 10:07
28

use this, is work for me:

@Column(name = "candidate_id", nullable=false)
private Long candidate_id;
@ManyToOne(optional=false)
@JoinColumn(name = "candidate_id", insertable=false, updatable=false)
private Candidate candidate;
Redouane nomade
  • 291
  • 3
  • 3
11
@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;
}

If you have already mapped a column and have accidentaly set the same values for name and referencedColumnName in @JoinColumn hibernate gives the same stupid error

Error:

Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: com.testtest.SomeCustomEntity column: COLUMN_NAME (should be mapped with insert="false" update="false")

dbow
  • 579
  • 7
  • 17
  • 2
    A key point here for me was that the error says "should be mapped with insert=false update=false" but the actual parameters/methods should be "insertable=false, updatable=false". – Night Owl Jun 22 '17 at 21:35
1

Hope this will help!

@OneToOne(optional = false)
    @JoinColumn(name = "department_id", insertable = false, updatable = false)
    @JsonManagedReference
    private Department department;

@JsonIgnore
    public Department getDepartment() {
        return department;
    }

@OneToOne(mappedBy = "department")
private Designation designation;

@JsonIgnore
    public Designation getDesignation() {
        return designation;
    }
Multi Cabz
  • 11
  • 1
0

Take care to provide only 1 setter and getter for any attribute. The best way to approach is to write down the definition of all the attributes then use eclipse generate setter and getter utility rather than doing it manually. The option comes on right click-> source -> Generate Getter and Setter.

romil gaurav
  • 1,003
  • 6
  • 21
  • 40
0

This means you are mapping a column twice in your entity class. Explaining with an example...

    @Column(name = "column1")
    private String object1;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "column1", referencedColumnName = "column1")
    private TableClass object2;

The problem in the above code snippet is we are repeating mapping...

Solution

Since mapping is an important part, you don't want to remove that. Instead, you will remove

    @Column(name = "column1")
    private String uniqueId;

You can still pass the value of object1 by creating a object of TableClass and assign the String value of Object1 in it.

This works 100%. I have tested this with Postgres and Oracle database.

Rishabh Agarwal
  • 1,109
  • 1
  • 9
  • 19
0

We have resolved the circular dependency(Parent-child Entities) by mapping the child entity instead of parent entity in Grails 4(GORM).

Example:

Class Person {
    String name
}

Class Employee extends Person{
    String empId
}

//Before my code 
Class Address {
    static belongsTo = [person: Person]
}

//We changed our Address class to:
Class Address {
    static belongsTo = [person: Employee]
}