7

During the creation of the database by Hibernate, it is adding a unique key constraint for the foreign key id_student in oe_iv_student_lang table because we have to implement the Serializable interface which results in Hibernate not letting us add multiple rows with same parent foreign key in its corresponding child table.

I have attached the snippet for better understanding..

Student Class:

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name = "oe_iv_student")
public class OeIvStudent {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id_student")
    private Integer idStudent;
}

Student Lang Class:

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name = "oe_iv_student_lang")
public class OeIvStudentLang implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id_student_lang")
    private Integer idStudentLang;

    @OneToOne
    @JoinColumn(name = "id_student")
    private OeIvStudent idStudent;

    @Column(name = "ln_code")
    private String lnCode;
}

Location Class:

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name = "oe_locations")
public class OeLocations {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id_location")
    private Integer idLocation;

    @OneToOne
    @JoinColumn(name = "id_student", referencedColumnName = "id_student")
    private OeIvStudentLang idStudent;

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

The reason I use Serializable interface is that I am mapping an Object of OeIvStudentLang class in OeLocations but the column being referenced is of OeIvStudent class. Having an Object of OeIvStudentLang makes it easier for me to naivgate throught the tables, i.e.

OeLocations->OeIvStudentLang->OeIvStudent

If I do not use Serializable in the OeIvStudentLangclass, Hibernate throws a Exception saying that OeIvStudentLang is not Serializable when I work with OeLocations class.If I were to use an Object of OeIvStudent instead, I would not be able to navigate to the lang class from OeLocations.

Please have a look and suggest what to be done.

Thanks :)

PySaad
  • 1,052
  • 16
  • 26
  • 2
    please share your mapping annotations or xml definitions for that association. – ikettu Jul 24 '17 at 09:40
  • This is not a useful question if you have not included any source code. There is no way to tell where your code is going wrong based solely on a cartoon of two database tables. Please update your question to contain more information about your approach, including your Hibernate/JPA table mappings. – Ben M Jul 27 '17 at 01:47
  • @ikettu Please review. I've shared the same. – PySaad Jul 27 '17 at 04:33
  • @Ben Welcome to cartoon! Here, is my source code. Please review it and let me know your valuable suggestions. – PySaad Jul 27 '17 at 04:33
  • Just to clarify, in the question you mention `oe_iv_student_lang` but that's not in the code, you did in fact mean `oe_student_lang`, yes? – Ben M Jul 27 '17 at 04:48
  • @Ben Yes it refers to ```oe_student_lang``` – PySaad Jul 27 '17 at 05:05

3 Answers3

3

This hasn't anything to do with implementing Serializable.

You've defined the relationship between OeIvStudentLang and OeIvStudent as @OneToOne. This means that every OeIvStudentLang has exactly one OeIvStudent. As you've even stated, this should be a One-To-Many relationship, thus you need to change your mapping from @OneToOne to @OneToMany and it should remove this unique constraint.

For reference:

A one-to-one association is similar to many-to-one association with a difference that the column will be set as unique.

Ben M
  • 1,833
  • 1
  • 15
  • 24
  • Even if you define that relationship as `@ManyToOne` it is still generating the same unique constraint on that table? – Ben M Jul 27 '17 at 04:47
  • Yes it is creating. The problem is with Serializable. If we remove this Serializable it is not creating unique. But it gives error in my program – PySaad Jul 27 '17 at 05:12
  • That's... very strange. Is there a reason you've marked some classes as Serializable but some not? – Ben M Jul 27 '17 at 05:13
  • how about setting `@JoinColumn(..., unique=false)`? – Ben M Jul 27 '17 at 05:16
  • 1
    The `@OneToOne` is definitely wrong (which isn't to say that there isn't also another problem involving `Serializable`). You have it both where @Ben points out, and also from `OeIvStudent` to `OeCountries`, saying that each student has a unique country and no country has more than one student... unlikely to be your intention. Review all your uses of relationships to eliminate the possibility of one of those being part of the problem. – Paul Hicks Jul 28 '17 at 00:27
  • Hii @PaulHicks If I'm using ```@OneToMany``` . Getting error as "Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements" – PySaad Aug 01 '17 at 06:15
  • You don't want OneToMany: that's for when one student has many countries. You want either ManyToOne or ManyToMany, depending on your requirements. – Paul Hicks Aug 01 '17 at 21:45
1

I suspect, the problem lies not in H2 but in the (possibly lacking) definition of the reference in the child entity. Can you show us the lines were the entities are defined.

probably how-to-reference-a-parents-id-in-a-childs-id-with-jpa-hibernate

can help

aschoerk
  • 3,333
  • 2
  • 15
  • 29
  • I've shared the mappings. Please let me know if you face any issue for same. – PySaad Jul 27 '17 at 04:34
  • Shouldn't Location reference the primary Key in studentlang? Additional to the change to ManyToLang there? Or should it reference Student? – aschoerk Jul 27 '17 at 05:04
  • We have to join it to ```id_student``` because there are two entries in student lang table with different ```ln_code``` corresponding to student table or location table for field ```ln_code``` and we cannot know which field to refer by referencing it to primary key. – PySaad Jul 27 '17 at 05:35
  • So why not use a location_id in the lang entity, get rid of ln_code and deliver location.code instead? the onetoone relationsship is to student_id,ln_code not student_id. So better put location_id into lang entity and define the locations relation by using referenceColumn location_id. I think using both name and referencedColumnName in a Onetoone relationship makes no sense. – aschoerk Jul 27 '17 at 07:33
0

you have to map it as @OneToMany relationship and change id_student column as a set entity

shady
  • 3
  • 3