Hibernate: Join table to a join table annotation - java

How do you create an annotation for the following case:
Table A
id
name
Table B
id
name
Table C
id
name
Table AB
a_id
b_id
Table ABC
id
a_id
b_id
c_id
name
How can you represent table ABC on hibernate using annotations?
Table AB is not an object it is used as a table join between tables A and B.
The annotation for A and B would look something like this:
For A:
#OneToMany(cascade=CascadeType.ALL)
#JoinTable(name="AB",
joinColumns={#JoinColumn(name="a_id", referencedColumnName="id")},
inverseJoinColumns={#JoinColumn(name="b_id", referencedColumnName="id")})
private Set bs;
For B:
#OneToMany(cascade=CascadeType.ALL)
#JoinTable(name="AB",
joinColumns={#JoinColumn(name="b_id", referencedColumnName="id")},
inverseJoinColumns={#JoinColumn(name="a_id", referencedColumnName="id")})
private Set as;
Thanks in Advance.

I would have done something like that :
A:
#ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.LAZY)
#JoinTable(name = "AB", joinColumns = #JoinColumn(name = "A_ID",
referencedColumnName = "ID"), inverseJoinColumns = #JoinColumn(name = "B_ID",
referencedColumnName = "ID"))
private List<B> bs;
Same for B.
ABC:
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "A_ID")
private A a;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "B_ID")
private B b;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "C_ID")
private C c;

Related

About the use of JPA ElementCollection

I used the ElementCollection annotation on a List object,
#ElementCollection(fetch = FetchType.EAGER)
#CollectionTable(
name = "a",
joinColumns = {#JoinColumn(name = "a_id", referencedColumnName = "a_id")},
foreignKey = #ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT)
)
private List<b> bs;
public class b{
#Column
private String bId;
#Column
private String bName;}
Is there a way to create a query dynamically through the name attribute in b by creating a Predicate

Java Spring + Hibernate "Cannot add or update a child row"

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (ravermeister.artist_recordlabel, CONSTRAINT FK_9dgdyft45droyopxsqijwb1dx FOREIGN KEY (artist_id) REFERENCES artist (id))
Artist class
#Entity
#Repository
#Data
#NoArgsConstructor(force = true)
public class Artist {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Column(name = "artist_firstname")
private String artist_firstname;
#Column(name = "artist_secondname")
private String artist_secondname;
#Column(name = "artist_nickname")
private String artist_nickname;
#ManyToMany (fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
#JoinTable(name = "artist_recordlabel", joinColumns = #JoinColumn(name = "artist_id"),
inverseJoinColumns = #JoinColumn(name = "label_id"))
private Set<RecordLabel> recordLabels;
#ManyToMany (fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
#JoinTable (name = "artist_musicrelease", joinColumns = #JoinColumn (name = "artist_id"),
inverseJoinColumns = #JoinColumn (name = "musicrelease_id"))
private Set <MusicRelease> musicReleaseSet;
and RecordLabel class
#Entity
#Repository
#Data
#NoArgsConstructor(force = true)
public class RecordLabel {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Column(name = "label_name")
private String label_name;
#Column(name = "label_country")
private String label_country;
#ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
#JoinTable(name = "artist_recordlabel", joinColumns = #JoinColumn(name = "label_id"),
inverseJoinColumns = #JoinColumn(name = "artist_id"))
private Set<Artist> artistsList;
Please follow this guide for a many-to-many relation
http://www.baeldung.com/hibernate-many-to-many
I think this error means that you are trying to insert/update into RecordLabel table a artist_id value that does not exist in Artist table.

#JoinTable to join three tables

How can I use #JoinTable to join three tables?
I have three tables:
user:
id, name
post:
id, date
company:
id, name
I want to create a new table with the following columns:
user_id, post_id, company_id.
I used:
#JoinTable(name = "new_table", joinColumns = #JoinColumn(name = "user_id"),
inverseJoinColumns = #JoinColumn(name = "post_id"))
However, I am not sure how to add the third column.
You must not will use #JoinTable annotation. The #JoinTable annotation is used only to #ManyToMany relationship.
You need create a new Entity with three field, and each field must has the #ManyToOne and #JoinColumn annotation.
For Instance:
#Entity
#Table(name = "table_name")
class NewEntity {
//Id and anothers fields
#ManyToOne
#JoinColumn(name = "user_id")
private User user;
#ManyToOne
#JoinColumn(name = "post_id")
private Post post;
#ManyToOne
#JoinColumn(name = "company_id")
private Company company;
//getters and setters
}

Order by using intermediate table column in JPA

I have Class Product (corresponding to PRODUCT table)
Class Product {
#Id
#Column(name = "PRODUCT_ID")
private Long id;
#Column(name = "NAME")
private String name;
//other attributes
}
I have another class Owner (corresponding to OWNER table)
Class Owner{
#Id
#Column(name = "OWNER_ID")
private Long id;
#Column(name = "NAME")
private String name;
}
I have an intermediate table named PRODUCT_OWNER (a product can have multiple owners).
The PRODUCT_OWNER table is something like this.
_______________________________________
| PRODUCT_ID | OWNER_ID | DISPLAY_ORDER |
|____________|__________|_______________|
Inside my Product class I have written a join statement to perform join using intermediate PRODUCT_OWNER table
#OneToMany(targetEntity = Owner.class, cascade = { CascadeType.ALL, CascadeType.MERGE }, fetch = FetchType.LAZY)
#JoinTable(name = "PRODUCT_OWNER",
joinColumns = { #JoinColumn(name = "PRODUCT_ID") },
inverseJoinColumns = { #JoinColumn(name = "OWNER_ID") })
private Set<Owner> productOwners = new HashSet<Owner>(0);
I have a column in my intermediate table as DISPLAY_ORDER. I want to sort the final Set productOwners using DISPLAY_ORDER. Is this possible in above approach. Please advice.
Hi you can try to add this to your JoinTable
#OneToMany(targetEntity = Owner.class, cascade = { CascadeType.ALL, CascadeType.MERGE }, fetch = FetchType.LAZY)
#JoinTable(name = "PRODUCT_OWNER",
joinColumns = { #JoinColumn(name = "PRODUCT_ID") },
inverseJoinColumns = { #JoinColumn(name = "OWNER_ID") })
#OrderColumn(name="DISPLAY_ORDER")
private List<Owner> productOwners = new HashSet<Owner>(0);

JPA Annotation issue

I have a Table A , Table AB , TABLE B , Table AB has foreign key references to Table A and Table B. There is a One to One relation between Table A and Table AB.and Many to one between Table B and Table AB.
My question is if i am saving domain for table B, it is saving data in table AB but not in A Please let me know if this is the expected behavior or can i save all data in all other tables just by calling save on Object B
Class A
{
#OneToOne(mappedBy="abpk.a")
#Cascade({ org.hibernate.annotations.CascadeType.ALL,
org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
private AB ab;
}
#Entity
#AssociationOverrides({
#AssociationOverride(name = "abpk.a", joinColumns = #JoinColumn(name = "colA", referencedColumnName = "colA")),
#AssociationOverride(name = "abpk.b", joinColumns = #JoinColumn(name = "Colb", referencedColumnName = "colB")) })
Class AB
{
ABPK abpk = new ABPK();
A a;
B b;
//inner class
class ABPK
{
A a;
B b;
#OneToOne(fetch = FetchType.LAZY)
#Cascade({ org.hibernate.annotations.CascadeType.ALL,
org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
#JoinColumn(name="b")
//Getter for A
GetA();
#ManyToOne(fetch = FetchType.LAZY)
//Getter for B
GetB();
}
}
Class B
{
#OneToMany(fetch = FetchType.LAZY, mappedBy = "abpk.b")
#Cascade({ org.hibernate.annotations.CascadeType.ALL,
org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
private List<AB> abList;
}
That depends on how you have set your cascade policies. If you have set it to CASCADE_TYPE ALL, then theoretically it should persists.
But in any case, it is better to wire up both sides of a relationship when you are trying to persist associations.

Categories