Store Custom Object Attributes as Columns in Hibernate - java

how can we generate table using custom object attribute as table column
private class CustomObject {
String attr1;
String attr2;
}
#Entity
#Table(name = "result")
public class Result {
#Column
private String id;
#Column
public CustomObject cobject;
}
RESULT table generate as follow
id
attr1
attr2

From Hibernate_User_Guide documentation:
PA defines two terms for working with an embeddable type: #Embeddable
and #Embedded. #Embeddable is used to describe the mapping type itself
(e.g. Publisher).#Embedded is for referencing a given embeddable type
(e.g. book.publisher).
So you can annotate your classes like below:
#Embeddable
private class CustomObject {
String attr1;
String attr2;
}
#Entity
#Table(name = "result")
public class Result {
#Column
private String id;
#Embedded
public CustomObject cobject;
}

Related

Hibernate embed a mapped superclass

I am trying to use #ElementCollection with a set of classes which are all inherited from a #MappedSuperclass but when persisting to the database there is no column to identify which subclass was created and therefore will fail when trying to retrieve it from the database. If I change the class to make it an entity instead it will then work but I need it to be #Embeddable to work with #ElementCollection
Below is the code:
#Entity
public class A {
private String attr1;
private String attr2;
....
#ElementCollection
private List<B> list;
....
}
Superclass:
#Embeddable
#MappedSuperclass
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class B {
private String attr3
private String attr4
....
}
Subclass1:
#Embeddable
#DiscriminatorValue("B1")
public class B1 extends B {
private String attr5
....
}
Subclass2:
#Embeddable
#DiscriminatorValue("B2")
public class B2 extends B {
private String attr6
....
}
Thanks in advance
#ElementCollection is for basic or embeddable values which both have no concept of inheritance. If you want inheritance, you need to model the value as entity and then use #OneToMany. From a relational mapping perspective, the two mappings are almost the same:
#Entity
public class A {
private String attr1;
private String attr2;
....
#OneToMany(mappedBy = "a")
private List<B> list;
....
}
#Entity
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class B {
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "a_id")
private A a;
private String attr3
private String attr4
....
}

"Object was not of the specified subclass [com.app.sportapp.entity.User] : Discriminator: player; - Hibernate, SpringBoot

I am trying to get all users from my database. I am using Postgresql, Hibernate and SpringBoot.
Not only that, but I have a table User that is in association with table Sport and Team table.
User.java
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "User_Type")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String firstName;
private String lastName;
private String username;
private String email;
private String password;
private String contactNumber;
}
Player.java
#Entity(name = "Players")
#DiscriminatorColumn(name="player", discriminatorType= DiscriminatorType.STRING)
#DiscriminatorOptions(force=true)
public class Player extends User {
private String dateOfBirth;
private String notes;
}
Coach.java
#Entity(name = "Coaches")
#DiscriminatorColumn(name="coach", discriminatorType= DiscriminatorType.STRING)
#DiscriminatorOptions(force=true)
public class Coach extends User{
}
When I am trying to test my app to get all users from database with Postman I am getting following error:
"Object [id=1] was not of the specified subclass [com.app.sportapp.entity.User] : Discriminator: player; nested exception is org.hibernate.WrongClassException: Object [id=1] was not of the specified subclass [com.app.sportapp.entity.User] : Discriminator: player"
The problem is your mapping, you are overriding/redefining the #DiscriminatorColumn. You should use #DiscriminatorValue instead.
The #DiscriminatorColumn defines which column contains the value to use for mapping the row to the proper entity class. With #DiscriminatorValue you specify which value maps to which class.
Your code should look something like this.
#Entity(name = "Players")
#DiscriminatorValue("player")
#DiscriminatorOptions(force=true)
public class Player extends User {
private String dateOfBirth;
private String notes;
}
#Entity(name = "Coaches")
#DiscriminatorValue("coach")
#DiscriminatorOptions(force=true)
public class Coach extends User{
}
Additionally, you might want to make your user abstract and add #MappedSuperclass to it as well.
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "User_Type")
#MappedSuperclass
public abstract class User { ... }
Unless there are also users that aren't players or coaches in your system (but then you would need an additional #DiscriminatorValue for that as well.

Is there a way to use share embeddable object in Hibernate?

I have a situation with repeatable class fields which I want to mark as #embeddable, however the question is - does JPA allow re-utilizing a class multiple times as embeddable in other different classes?
E.g. my embeddable class looks as follows:
#Embeddable
#Data
public class Audit{
private String name;
private Audit auditor;
private LocalDateTime creationDate;
}
Is it possible to embed the Audit into multiple different classes as for ex.:
#Entity
#Table(name = "BANK")
public class Bank{
#Id
private Long id;
#Column(name = "BANK_NAME")
private String bankName;
#Embedded
private Audit audit;
}
AND
#Entity
#Table(name = "CORPORATION")
public class Corporation{
#Id
private Long id;
#Column(name = "CORPORATION_NAME")
private String corporationName;
#Embedded
private Audit audit;
}
Historically Hibernate called these components. JPA calls them embeddables. Either way, the concept is the same: a composition of values.
Most often, embeddable types are used to group multiple basic type mappings and reuse them across several entities.
Java Code Example:
#Data
#Entity(name = "Book")
public class Book {
#Id
#GeneratedValue
private Long id;
private String title;
private String author;
private Publisher publisher;
}
#Data
#Embeddable
public static class Publisher {
#Column(name = "publisher_name")
private String name;
#Column(name = "publisher_country")
private String country;
}
And this is SQL to show how your table should look like:
create table Book (
id bigint not null,
author varchar(255),
publisher_country varchar(255),
publisher_name varchar(255),
title varchar(255),
primary key (id)
)
More details can be found in the documentation :)

One to One Weak Entity Mapping JPA

I have a Entity Class
#Entity
Class Search
{
#Id
private Long SearchID;
private String Type;
}
and another Entity Class ( SearchResults which is a weak Entity that depends on Search Class for its Primary Key
#Entity
Class SearchResults
{
#???
private Long SearchID;
}
What annotation should i use to assign "SearchID" of "Search" Entity class as my primary key in my weak Entity " SearchResults"
Using the JPA concept of Shared Primary Key, you can map your relationship as follows:
Your main class:
#Entity
public class Search {
#Id
private Long searchID;
private String type;
}
Derived Identifier with Single Attribute
#Entity
public class SearchResults {
#Id
#OneToOne
#JoinColumn(name = "SEARCHID")
private Search search;
}
Deriver Identifier with Shared Mappings
#Entity
public class SearchResults {
#Id
private Long searchID;
#MapsId
#OneToOne
#JoinColumn(name = "SEARCHID")
private Search search;
}
Full article here: http://vard-lokkur.blogspot.com.br/2014/05/onetoone-with-shared-primary-key.html
SearchResult does not have to be an entity.
While it can be mapped as an Enity with a shared PK as suggested in the other answer, as a Weak entity it cannot exist independently of its associated Search and so can be mapped as an Embeddable.
https://en.wikibooks.org/wiki/Java_Persistence/Embeddables
#Entity
public class Search
{
#Id
private Long SearchID;
private String Type;
#ElementCollection
#CollectionTable(....)
private Set<SearchResults> results;
}
#Embeddable
public class SearchResults
{
//does not need an Id
//other fields
}

How to have a composite id where fields are available in multiple embedded classes

The composite key for my table is userid, orderno, orderstatus.
Entity class is
#Entity
public class OrTest implements java.io.Serializable {
private UserInfo user; //UserInfo is embedded class having userid
private OrderInfo order; // OrderInfo is embedded class having order
private Status status; //Status is embedded class having orderstatus
//Contains other misc info
}
How to use embeddedid in this scenario where my actual composite key fields are split across multiple embedded classes.
You can have EmbeddedId class contain all the 3 keys. like below
public class OrTextPk implements Serializable{
#Column(name="userId")
public String userId;
#Column(name="orderNo")
public String orderNo'
#Column(name="orderStatus")
public String orderStatus;
}
Now, in the OrText class you can do the following.
#Entity
public class OrTest implements java.io.Serializable {
#EmbeddedId
private OrTextPk id;
#OneToOne(fetch=FetchType.LAZY)
#JoinColumn(name="userId")
private UserInfo user; //UserInfo is embedded class having userid
.
.
.
so on...
}
In addition to the solution posted by #Zeus, You only need to do minor change in following way.
Composite PK
public class OrTextPk implements Serializable{
public String userId;
#Column(name="orderNo")
public String orderNo'
#Column(name="orderStatus")
public String orderStatus;
}
Main entity class
#Entity
public class OrTest implements java.io.Serializable {
#EmbeddedId
private OrTextPk id;
#OneToOne(fetch = FetchType.LAZY)
// Note: it will help to map value of userId (UserInfo) to Pk object
#MapsId("userId")
#JoinColumn(name = "userId")
private UserInfo user; //UserInfo is embedded class having userid
.
.
.
so on...
}
Now, on setting New/Persisted object of UserInfo(user), value of userId of UserInfo object will be assigned to userId of OrTextPk while persisting OrTest object.

Categories