I have a table A which has a composite key, say columns A, B and C.
Another table B with some added fields (child of A) will share the primary key A,B,C
Basically when data is inserted in TABLE A, same copy will be there in C with some added information.
Tried Id class , join columns etc.
Sometimes broken id error comes or other .
Please check the structure and let me know if you can help.
Class BIdClass
#Id
#Column(name="A")
private Integer a;
#Id
#Column(name="B")
private Integer b;
#Id
#Column(name="C")
private Integer c;
#Id
#OneToOne(optional=true)
#JoinColumns({
#JoinColumn(name="A", referencedColumnName="A"),
#JoinColumn(name="B", referencedColumnName="B"),
#JoinColumn(name="C", referencedColumnName="C)
})
private ClassA a;
#IdClass
Class B{
#Id
#Column(name="A")
private Integer a;
#Id
#Column(name="B")
private Integer b;
#Id
#Column(name="C")
private Integer c;
#MapsId("a")
#OneToOne
#JoinColumns({
#JoinColumn(name="A", referencedColumnName="A"),
#JoinColumn(name="B", referencedColumnName="B ),
#JoinColumn(name="C", referencedColumnName="C)
})
private ClassA a;
}
Class A{
#OneToOne(mappedBy="a",cascade=CascadeType.ALL)
private ClassB b;
Related
I'm having three entities which are being saved into the DB. For instance we have 3 entities A, B and C. A is having OneToOne mapping with B and ManyToOne mapping with C which is uni-directional.
public class A {
#Id
#GeneratedValue
private int id;
private String number;
//Other fields declared
#PostPersist
private void onSaving(){
number = "STU" + id;
}
}
public class B {
#Id
#GeneratedValue
int otherID; //primary key for B
//Other fields declared
#OnetoOne(targetEntity = A.class, cascade= CascadeType.ALL)
#JoinColumn(name = "id") // id is the primary key of class A
private A a;
}
public class C {
#Id
#GeneratedValue
int otherID; //primary key for C
//Other fields declared
#ManytoOne
#JoinColumn(name = "id") // id is the primary key of class A
private A a;
}
Below is the service class for the above entities
#Service
public class testService {
#Autowired
private BRepo bRepo; // BRepo is the interface which is extending the JPARepository.
#Autowired
private CRepo cRepo; // CRepo is the interface which is extending the JPARepository.
#Transactional
public A saveEntity(B b, List<C> c) {
bRepo.save(b);
cRepo.saveAll(c);
return b.getA();
}
}
The entity fields/data are getting perfectly saved into the DB, the only issue I'm facing is with the #PostPersist annotation. My requirement is when save is performed, the number field/variable of entity A should be saved as "STU" + id(primary key for A), but in the DB it is saving as STU0 every time I perform save.
I'm unable to find the root cause for this over the internet. Requesting you to please help me debug this issue. Thank you.
The issue got resolved after I added, strategy as IDENTITY
#GeneratedValue(strategy = GenerationType.IDENTITY)
Suppose i have two entity classes with embeddable/composite keys...
Eg.
#Entity
public class X
{
#EmbeddedId private Embed id;
......
#Embeddable public class Embed
{
private int a;
private int b;
.......
#Entity
public class Y
{
#EmbeddedId private YEmbed id;
......
#Embeddable public class YEmbed
{
private int a1;
private int b1;
.......
Now in the above scenario i want to define some kind of mapping eg. OnetoOne or ManytoOne or any other mapping between Tables X and Y using composite key fields a with a1 or b with b1 ???
How can i achieve this in spring-jpa/hibernate ???
Thanks in advance....
I have 2 entities O and D with a one to many relationship from O (one) to D (many). The relationship itself has an attribute - count.
What is the best way to model this using hibernate?
What I have currently is another entity OD representing the relationship. It has its own artificial key
The abbreviated version of the entities is as below
#Entity
class O {
#Id
private Long id;
#OneToMany(mappedBy = "o")
private Set<OD> ods;
}
#Entity
class OD {
#Id
private Long id;
#ManyToOne
private O o;
// This is uni-directional reln
#OneToOne
private D d;
private int count;
}
Is this the best way? I do not like the fact that the relationship has its own id, but is there a better way to model this relationship?
You can model the OD as #Embeddable, and change the owning side from #OneToMany to #ElementCollection e.g.
#Entity
public class O {
#Id
private Long id;
#ElementCollection
#CollectionTable( name = "OD")
private Set<OD> ods;
}
#Embeddable
public class OD {
// This is uni-directional reln
#OneToOne
private D d;
private int count;
}
The DDL statements would be almost the same with the distinction that the life-cycle of the OD would always be dependent on the life of its parent object, and would not hold an identity of its own
Sorry if my post is duplicated or the tittle doesn't describe the topics, because I don't know how to describe this in the tittle, I look on internet, but I didn't find the solution.
I am using Java and JPA. The problem is the next :
I have a class A with an autogenerated key :
class A{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private List<B> listB;
}
And the class B with the id of this clas:
class B {
#EmbeddedId
private Bid id;
private String att;
}
class Bid {
private int idA;
private String text;
}
In a controller I want to create an object A, the problem is when I created the object A, I need to create the object B where the id of B contains the id of A which is autogenerated, and it is created in the moment when the entity is mapped to de database, I dont't know how to set the id autogenerated of A into the idB, maybe I should query to de database asking what is the las id of classA, but it seem bad.
Thanks in advance
Your case is a derived identifier case, where your entity B's identity was derived from the primary key of A. You can use #MapsId annotation for this case and your entities can be restructured like this:
#Entity
public class A {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
#OneToMany(mappedBy="a")
private List<B> listB = new ArrayList<B>();
...
}
#Entity
public class B {
#EmbeddedId
private BId id;
#ManyToOne
#MapsId("idA")
private A a;
...
}
#Embeddable
public class BId {
private int idA;
private String att;
...
}
This is how you would persist the entities:
A a = new A();
BId bid = new BId();
bid.setAtt("text"); // notice that the idA attribute is never manually set, since it is derived from A
B b = new B();
b.setId(bid);
b.setA(a);
a.getListB().add(b);
em.persist(a);
em.persist(b);
See sample implementation here.
It would be useful to know which is the case scenario you are trying to solve in general because the structure you are using seems unnecessarily complex.
What is your real goal?
How can i bind two columns, using #OneToOne annotation?
Lets say I've 2 tables A and B.
Table A:
id1 (primary key)
id2 (pk)
other columns
Table B:
id1 (pk)
id2 (pk)
other columns
In class A i want to write something like this:
#OneToOne(fetch = FetchType.EAGER, targetEntity = B.class)
#JoinColumn(name = "id1 and id2", referencedColumnName = "id1 and id2")
private B b;
Is it possible to do this using annotations?
Thanks.
What you need is composite keys.Use either #IdClass or #EmbeddedId
Example of #EmbeddedId something like this.
your composite key class:
#Embeddable
public class CompositePK implements Serializable {
protected Integer id1;
protected Integer id2;
// equals, hashCode
}
Your Enity class :
#Entity
public class A{
#EmbeddedId
private CompositePK compkey;
#OneToOne(optional=true, mappedBy="A")
private B b;
........
}