I have two table with composite keys which shares a common column as part of their composite key. Below is by ER:
Table A: schemaId,aID
Table B: schemaId,bID,aID
Here scheId is contant value.
A and B has OneToMany relation(i.e., A record has multiple B records)
When I form a ManyToOne relation in Table B, I am doing below:
#ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name = "aID", referencedColumnName = "aID")
#JoinColumn(name = "schemaId", referencedColumnName = "schemaId")
private A a;
Above works fine(records get inserted), but I require schemaId as part of Entity B as there are other table which share this composite key from Table B.
In order to maintain the filed in entity if I change #JoinColumn with (insert="false" update="false"), value is passing as null for schemaId as it will treat as optional one.
Entity A:
#IdClass(APK.class)
#Entity
public class A
{
#Id
private Integer schemaId;
#Id
private Integer aId;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "a")
private List<B> blist;
...
}
public class APK implements Serializable{
private Integer schemaId;
private Integer aId;
}
Entity B:
#IdClass(BPK.class)
#Entity
public class B
{
#Id
private Integer schemaId;
#Id
private Integer bId;
private Integer aId;
#ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name = "aID", referencedColumnName = "aID")
#JoinColumn(name = "schemaId", referencedColumnName = "schemaId")
private A a;
}
public class APK implements Serializable{
private Integer schemaId;
private Integer bId;
}
Related
i'm kinda struggling mapping the following schema with hibernate
table_a (A1_ID,A2_ID) --> PK = (A1_ID, A2_ID)
table_b (A1_ID, A2_ID, B1_ID) --> PK =(A1_ID, A2_ID, B1_ID)
where table_b's A1_ID and A2_ID should be foreingkey referencing respective table_A's columns
There is a one-to-many from TABLE_A to TABLE_B where TABLE_B's primary key is partially shared with TABLE_A's primary key
What I've tried so far
#Data
#Entity
#Table(name = "table_a")
#IdClass(TableA.TableAKey.class)
public class TableA {
#Id
#Column(name = "A1_ID)
private String a1_id;
#Id
#Column(name = "A2_ID)
private String a2_id;
#OneToMany(mappedBy = "tableA",fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<TableB> tableB;
#Data
static class TableAKey implements Serializable {
private String a1_id;
private String a2_id
}
}
**CHILD ENTITY**
#Data
#Entity
#Table(name = "table_b")
#IdClass(TableB.TableBKey.class)
public class TableB {
#Id
#Column(name = "B1_ID)
private String b1_id;
#Id
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumns({
#JoinColumn(name = "a1_id", insertable = false, updatable = false),
#JoinColumn(name = "a2_id", insertable = false, updatable = false)
)}
private TableA tableA;
#Column(name = "A1_ID)
private String a1_id;
#Column(name = "A2_ID)
private String a2_id;
#Data
static class TableAKey implements Serializable {
private String b1_id;
private TableA tableA;
}
}
I was expecting i could be able to do something like this:
TableA tableA = new TableA();
t.setA1_id("a1id");
t.setA2_id("a2id");
TableB tableB = new TableB();
tableB.setB1Id("b1Id");
tableA.setTableB(Arrays.asList(tableB));
tableARepository.save(tableA);
And the code above I was expecting to "magically" perform the following insert at DB
INSERT INTO table_A (A1_ID,A2_ID) VALUES ('a1id',a2id');
INSERT INTO table_B (A1_ID,A2_ID, B1_ID) VALUES ('a1id',a2id','b1id')
but instead i get a "the column index is out of range: n, number of columns n-1".
I also tried with some embeddedId approach, using referenceColumnName but nothing.
Am I doing something wrong in the mapping or in the object creation process?
The problem is a lot similar to the following
https://hibernate.atlassian.net/browse/HHH-14340
Simple example (hopefully). I have a primary key (using a sequence) in one table and that value is a partial FK into a child table. I see the Parent is trying to be saved with a generated sequence, but then I see an exception that the parentId in the embeddable is null while saving the child. The sequence value used for the parent is not being carried over to the child. I have tried many annotations and mappedBy/join column names but no luck.
Any pointers would be very much appreciated.
public class Parent {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "audit_seq")
#SequenceGenerator(name = "audit_seq", allocationSize = 5)
private Long id;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "parent")
private List<Child> childList = new ArrayList<>();
//Used to add child record o the parent
public void addChild(Child child) {
this.childList .add(child);
child.setParent(this);
}
}
#Embeddable
public class ChildId {
private Long parentId;
private String name;
}
public class Child {
#EmbeddedId
private ChildId id;
private String myCol;
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name = "parentId", insertable = false, updatable = false)
private Parent parent;
}
I was able to get this resolved with the use of a couple of annotations:
Parent class:
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "parent", orphanRemoval = true)
#PrimaryKeyJoinColumn
private List<Child> childList = new ArrayList<>();
Child class:
#ManyToOne
#MapsId("id")
#JoinColumn(name = "id")
private Parent parent;
Now all objects are being persisted when saving the parent with the appropiate sequence id.
I need help with resolving our problem with naming FK in JPA. We have one embeddable entity e.g. Foo which is used as collection in another one entity Bar.
embeddable entity:
#Embeddable
public class Foo{
#Column(name = "foo1")
private String foo1;
#Column(name = "foo2")
private String foo2;
}
main entity:
#Entity
#Table(name = "Bar")
public class Bar {
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
#Id
private Long id;
#ElementCollection
#CollectionTable(name = "foos", joinColumns = #JoinColumn(name = "bar_id", foreignKey = #ForeignKey(name = "foo_bar_fk"), nullable = false))
private List<Bar> bars;
}
When I generated tables in database (postgres) foreign key is called fdk44l345k64 instead foo_bar_fk. Can you tell me how to fix it? Thanks.
I use spring boot, with jpa (hibernate) and postgresql
I use composite key.
#Entity
#IdClass(SamplingsPK.class)
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Samplings {
#Id
#GeneratedValue
private Integer id;
#Id
private int year;
#OneToMany(mappedBy = "sampling", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Samples> samples = new ArrayList<>();
...
}
public class SamplingsPK implements Serializable {
private Integer id;
private int year;
public SamplingsPK(Integer id, int year) {
this.id = id;
this.year=year;
}
private SamplingsPK(){
}
#PrePersist
public void prePersist() {
year = LocalDate.now().getYear();
}
}
#Entity
public class Samples {
#Id
#SequenceGenerator(name = "samples_id_seq", sequenceName = "samples_id_seq", allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "samples_id_seq")
private Integer id;
private String sampleLetter;
#ManyToOne
#JoinColumns({
#JoinColumn(name = "sampling_id", referencedColumnName = "id"),
#JoinColumn(name = "sampling_year", referencedColumnName = "year")
})
private Samplings sampling;
}
That work fine
Instead of having an sequence in samples, I would like to have a composite key... SamplingsPK + sampleLetter.
Is it possible to do it, how to save a sample?
This is a "derived identity", so Samples could be mapped with an #IdClass like this:
#Entity
#IdClass(SamplesPK.class)
public class Samples {
#Id
#ManyToOne
#JoinColumns({
#JoinColumn(name = "sampling_id", referencedColumnName = "id"),
#JoinColumn(name = "sampling_year", referencedColumnName = "year")
})
private Samplings sampling;
#Id
private String sampleLetter;
}
public class SamplesPK {
SamplingsPK sampling; // matches name of attribute and type of Samplings PK
String sampleLetter; // matches name and type of attribute
}
Derived identities are discussed (with examples) in the JPA 2.2 spec in section 2.4.1.
hi have two tables in picture table a and table b as follows :
#Entity
#Table(name = "A")
public class A implements Serializable {
#Id
#SequenceGenerator(name = "JOURNAL_CATEGORY_ID_GENERATOR", allocationSize = 1, sequenceName = "clm_jounal_category_config_seq")
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "JOURNAL_CATEGORY_ID_GENERATOR")
#Column(name = "CLAIM_ID")
private String claimId;
#Column(name = "name")
private String name;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "country")
private List<ClaimDTLS> claimDetails;
}
B Primary Key:
#Embeddable
public class BPK implements Serializable {
#Column(name = "code")
private String code;
#Column(name = "CLAIM_ID")
private String claimId;
}
B Entity:
#Entity
#Table(name = "B")
public class B implements Serializable {
#EmbeddedId
protected BPK bpk;
#Column(name = "name")
private String name;
#MapsId("country_code")
#JoinColumn(name = "claimId", referencedColumnName = "claimId", insertable = false, updatable = false)
#ManyToOne
private A a;
}
when i try to persist object of A type in Db the value of table b claim id is not set and is intialized with zero.
Also primary key of table A is generated with a oracle sequence.
any help will be welcomed.
thanks in advance
Sequence values are numbers and when JPA use them as a generator it call the setter method of the entity PK. Now, you defined your PK as a string while you use a sequence and so no matching setter can be found. Change the type of you PK to be Long and things shall work