Hibernate/JPA - Is possible to have a children with parent's ID + another field? - spring

I am new using Hibernate and I am trying to know if is possible to change the primary key of a child component with a composite key. This is my parent component:
public class Person{
#Id
#Column(name = "id", unique = true)
private String id;
private String name;
private String surname;
}
This is my child component:
public class User extends Person {
private String email;
private String password;
}
I would like to identify my user with id+email key. Is that possible?

If your inherited entities share the same table, it wouldn't be possible, as in the database there can be only one primary key logic per table.
However if you have a inheritance strategy using joins, it would be possible I guess - check out Hibernate - Foreign and primary keys in inheritance

Related

Is possible to have a Composite Primary Key which components are entity foreign keys?

I have the following model:
(...)
#IdClass(BetID.class) //Primary Key, composite = userID+gameID
public class Bet {
(...)
//Primary Key
#ManyToOne
#Id
private User user; //Composite key:userID
#ManyToOne
#Id
private Game game; //Composite key:gameID
In which, of course, has the following Composite key:
public class BetID implements Serializable {
#OneToOne
private User user;
#OneToOne
private Game game;
Here, User and Game are foreign keys, but also entities. Problem is when I'm trying to handle, so I can't set/get the key as easy as having a normal key like:
#EmbeddedId BetID bet id because the id has to refer 2 attributes from Bet. So using #Getter and #Setter (with lombok) is not possible.
So, how can I handle this? Is even possible to have a key like this?
You can add a setter with two arguments:
public void setBetID(User user, Game game) {
this.betId = new BetID(user, game);
}

#ManyToOne Referencing a composite key in JPA

I have following entities
#Entity
#IdClass(SubjectId.class)
class Subject {
#Id
String name;
#Id
String volume;
........
}
class SubjectId {
String name;
String volume;
//constructor, getters and setters
..........
}
#Entity
class Student {
#Id
String studentId;
String subject;
String subjectVolume;
}
I want to map the fields subject and subjectVolume of class Student to composite primary key of class Subject as a #ManyToOne relationship. But I don't know what should I pass inside #ManyToOne(?).
Any help would be appreciated, thanks.
Edit:
I want to use the columns subjectName and subjectVolume as entity fields in class Student as well. I don't want to do student.getSubject().getSubjectName() instead I want student.getSubjectName().
You could just declare the relation this way (instead of declaring the fk fields):
class Student{
#Id
String studentId;
#ManyToOne // this is sufficient create foreign-key columns in the Student-table
Subject subject;
}
The generated columns of the Student table will have these names by default:
In case you need different column names you should look for the #JoinColumn annotation.
edit: to be able to directly call student.getSubjectName() you could still decide to include single parts of the composite foreign key additionally as entity properties, in this case you need to make sure to declare the second (duplicate) column mapping with insertable=false and updatable=false, since its value is already managed by the #ManyToOne fk:
#Entity
static class Student {
#Id
String studentId;
#ManyToOne
Subject subject;
#Column(name = "subject_name", insertable = false, updatable = false)
String subjectName;
}
However, I'd probably prefer simply declaring a custom getSubjectName() getter which just returns subject.getName().

Two tables connected via Primary Key

I have read about the use of #MapsId and #PrimaryKeyJoinColumn annotations, which sounds like a great options. I have two tables (UserList and UserInformation) which have a child, parent relationship, respectively; both classes below are abbreviated to just include the relevant columns. UserInformation's primary key value is always null and does not take the value of its parent column.
User Class
#Entity
#Data
#Table(name = "user_list")
public class UserList {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
// List of foreign keys connecting different entities
#OneToOne(mappedBy = "user")
#MapsId("id")
private UserInformation userInfo;
}
UserInformation Class
#Entity
#Data
#Table(name = "user_information")
public class UserInformation implements Serializable {
#Id
private Integer userId;
#OneToOne
private UserList user;
}
I would prefer to not use an intermediary class if possible. I'm not tied to MapsId or even this implementation if there is a better solution.
Thanks!
The question is not very clear to me, but I think you could improve the following in the modeling of the entity:
The #column annotation can only be omitted when the class parameter is called exactly the same as the database column, taking into account the table name nomenclature, could it be that the column is user_id ?, if so the id parameter should be :
#Id
#column(name="USER_ID")
private Integer userId;
In the user entity being id, it will match the DB ID field so the #column annotation is not necessary

Couchbase spring data jpa to generate composite primary key

Using Couchbase with Spring Data and JPA,
In my entity class How to create a Composite Key using two fields.
currently in Person class id is the primary key #Id
where I want combination of id and name will be primary key.
#Document
public class Person {
#Id
private String id;
#Field
private String name;
#Field
private String city;
I think you should be able to achieve what you want using the following -
#Document
public class Person {
#Id
#GeneratedValue()
String key;
#IdPrefix
String id;
#Field
#IdAttribute
String name;
#Field
private String city;
}
Use #IdSuffix if you want the value in id to be after the name . When constructing the above object don't assign a value to key variable yourself as the value doesn't get autogenerated if you provide one of your own as per docs - https://docs.spring.io/spring-data/couchbase/docs/current/reference/html/#couchbase.autokeygeneration.configuration .

JPA2 PrimaryKey vs Oracle Primary key

Is it possible that oracle table has a composite primary key oracle sequenceid +createtimestamp but the #Entity class we have just the #id (sequenceid) primary key ? Timestamp we are adding for the purpose of table partitions which we use for purging later. At the time of storing the entity we will add the timestamp value all the time. From the data point of view id alone is primary key for the record in this case. Can I create entity with primary key as id alone?
In this case you have to create composite primary key in # Entity class. You can as per below example
#Entity
#Table(name="RELEASE_PERSON")
#IdClass(ReleasePersonPK.class)
public class ReleasePerson implements Serializable {
#Column(name="ORDER_NO", nullable=false, precision=2)
private Integer orderNo;
#Id
#Column(name="RELEASE_ID", insertable=false,updatable=false)
private long releaseId;
#Id
#Column(name="PERSON_ID", insertable=false,updatable=false)
private long personId;
#ManyToOne
#JoinColumn(name = "PERSON_ID", referencedColumnName = "PERSON_ID")
private Person person;
#ManyToOne
#JoinColumn(name = "RELEASE_ID", referencedColumnName = "ID")
private Release release;
And your Id Class will be look like below
#Embeddable
public class ReleasePersonPK implements Serializable {
/**
*
*/
private static final long serialVersionUID = -6286499269052596345L;
private Person person;
private Release release;
In my example in ReleasePersone table we will have composite primary key from rRelease(ID) and Person (Person_id).
Let me know if you need anything else.
The answer is yes. as you said that the id will be unique in the table, it's definitely ok that just put sequenceId as PK in the entity. If you don't use hibernate to create the table or update the columns of table, it doesn't care what actually in the database.

Resources