I'm using #MappedSuperclass annotation in the following way:
#MappedSuperclass
public abstract class Recipient {
#Id
#Column(name = "id")
private int id;
#Column(name = "email")
private String email;
//GET, SET
}
I also have two entity classe, inherited from one:
public class Player extends Recipient{
//FIELD, GET, SET
}
and
public class Partner extends Recipient{
//FIELD, GET, SET
}
The thing is private int id filed in the class Player has an additional attribute:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
Is it possible to specify that? We can override attribute with annotation #AttributeOverride, but what about to add one?
Related
Suppose that I have a simple Hibernate entity with auto-incremented id.
#Entity
#Table(name = "product")
public class Product {
#Id
#GeneratedValue(strategy = IDENTITY)
private Long id;
private String name;
}
Is it possible to declare id as a type-safe variable? I could apply #EmbeddedId like this.
#Entity
#Table(name = "product")
public class Product {
#EmbeddedId
private ProductId id;
private String name;
#Embeddable
public static class ProductId implements Serializable {
#GeneratedValue(strategy = IDENTITY)
private Long id;
public Long getId() {
return id;
}
}
}
It works with client-generated IDs, but not with database-generated ones.
Has anyone solved similar problem? What are the possible approaches?
First, you need to annotate ProductId class with #Embeddable like this:
#Embeddable
public static class ProductId implements Serializable {
private Long id;
private String name;
}
And, when you save entity, you need to create an instance of ProductId with unique parameters (in your case it is "name" field) as well.
For more information, I suggest you to have a look at here
I have object with #Id (primary key) and this is some business UIID field and I want another Long technical Id for some reasons but when saving the object I get null from getObjectId field:
#Id
private String id;
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "object_id")
private Long objectId;
public Long getObjectId() {
return objectId;
}
public void setObjectId(Long objectId) {
this.objectId = objectId;
}
I have this storage class:
interface MyObjectStorage extends JpaRepository<MyObject, String>
And this is how I save it:
final MyObject saved = storage.saveAndFlush(toSave);
saved.objectId is null here..
And in my MySQL db the objectId field is marked not null auto increment..
PS. And I don't want this objectId field to be used by JPA when findById is executed.
Hibernate/JPA isn't able to automatically create a value for your non-id-properties. The #GeneratedValue annotation is only used in conjunction with #Id to create auto-numbers.
The solution (or work-around) suggested in this forum is to create a separate entity with a generated Id, something like this:
#Entity
public class GeneralSequenceNumber {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "object_id")
private Long objectId;
}
#Entity
public class MyEntity {
#Id ..
private Long id;
#OneToOne(...)
private GeneralSequnceNumber myVal;
}
try the following code
#Id must be a type of Integer or Long
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "object_id")
private Long objectId;
private String id;
public Long getObjectId() {
return objectId;
}
public void setObjectId(Long objectId) {
this.objectId = objectId;
}
interface MyObjectStorage extends JpaRepository<MyObject, Long>
Hibernate creates empty "ID" column in case of code like in this post.
How tune it to not create "ID" column ("ID" is exact name of created column) or this can not be changed?
#Entity
#Table(name = "CATEGORY_RELATIONS")
public class CategoryRelations implements Serializable {
private CategoryRelationsPrimaryKey id;
#Id
#Column(name = "CATEGORY_RELATIONS_CATEGORY_ID")
private String categoryId;
#Id
#Column(name = "CATEGORY_RELATIONS_PARENT_ID")
private String parentId;
//getters and setters
#Entity
#IdClass(CategoryRelationsPrimaryKey.class)
public class CategoryRelationsPrimaryKey implements Serializable {
protected long categoryId;
protected long parentId;
//euqals, hashCode
}
}
1) #IdClass should stand at entity, not at composite id class;
2) If you already marked id properties by #Id, no separate id property is required:
#Entity
#Table(name = "CATEGORY_RELATIONS")
#IdClass(CategoryRelationsPrimaryKey.class)
public class CategoryRelations implements Serializable {
#Id
#Column(name = "CATEGORY_RELATIONS_CATEGORY_ID")
private String categoryId;
#Id
#Column(name = "CATEGORY_RELATIONS_PARENT_ID")
private String parentId;
//...
}
public class CategoryRelationsPrimaryKey implements Serializable {
protected String categoryId;
protected String parentId;
// ...
}
If you need some property named id, make it transient to avoid mapping to a DB table column.
Suppose I have two hibernate entity classes: class Player and class Partner which both will be participate in a mailing. That's they are both contain the following fields:
String email;
Integer id;
String name
I want to create an interface as follows:
public interface Recipient{
public String getEmail();
public String getName();
public Integer getId();
}
Essentially, these classes will be something like the following:
#Entity
#Table(name = "player")
#Inheritance(strategy = InheritanceType.JOINED)
class Player implements Recipient
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name = "ps_id")
private String psId;
#Column(name = "login")
private String login;
#Column(name = "password")
private String password;
#Column(name = "email")
private String email;
//GET, SET and inherited method impl
}
This is the right way to do this or in hibernate shall not write an entity class, inherited one from another class/interface? Just POJO.
You can use #MappedSuperclass annotation on the interface class. AFAIK this is the right way to do it.
I have a PatientVisit.java that has a one to one mapping with the PatientVisitObject.java:
#Entity
#Table(name = "P_Visit")
public class PatientVisit extends Bean {
#Id
#Column(name = "PATIENT_VISIT_SEQ")
private Long patientVisitSeq;
#Column(name = "PATIENT_FIRST_NM")
private String firstName;
#Column(name = "PATIENT_LAST_NM")
private String lastName;
#Column(name = "PATIENT_MIDDLE_NM")
private String middleName;
#OneToOne
private PatientVisitObject pvo;
}
The PatientVisitObject.java has a composite key. I need to map key.patientVisitSeq to my patientVisitSeq in the PatientVisit.java.
#Entity
#Table(name = "Patient_V_O")
public class PatientVisitObject extends Bean {
#Id
private PatientVisitObjectKey key;
#Column(name = "FIELD")
private String field;
}
Here is the key:
#Embeddable
public class PatientVisitObjectKey implements Serializable {
#Column(name = "PATIENT_VISIT_SEQ")
private Long patientVisitSeq;
#Column(name = "PATIENT_VISIT_OBJECT_SEQ")
private Long patientVisitObjectSeq;
}
I have tried using the #JoinTable annotation and cannot get it right. Could someone please give me some direction. Thanks.
You need to use bidirectional mapping with PatientVisit being the inverse side of relationship:
public class PatientVisit extends Bean {
...
#OneToOne(mappedBy = "pv")
private PatientVisitObject pvo;
...
}
public class PatientVisitObject extends Bean {
#EmbeddedId
private PatientVisitObjectKey key;
#OneToOne
#MapsId("patientVisitSeq")
private PatientVisit pv;
...
}
See also:
#MapsId