Hibernate: Add column in subclass - java

Is there possibility to add new column in subclass of entity? Something like:
Base class:
#Entity
#Table(name = "users")
public class User {
#Column
private String login;
}
Subclass:
#Entity
#Table(name = "users")
public class UserWithField extends User {
#Column
private String field;
}
I don't want to change base class (User) at all. Would it work somehow?

Just create new class for new entity. Generally,In hibernate inheritance is used when you have two or more related tables.

Related

org.hibernate.MappingException: Unknown entity - Hibernate, SpringBoot, DTO pattern

I am trying to build a simple SpringBoot and Hibernate app using DAO and DTO pattern.
I am trying to save a list of users to the database.
When I am using User class it works fine, but when I am trying to use DTO CreateUserDto class I am getting the following error:
"Unknown entity: com.app.sportapp.dto.CreateUserDto; nested exception is org.hibernate.MappingException: Unknown entity: com.app.sportapp.dto.CreateUserDto"
There is a SingleTable inheritance where Player class and Coach class inherit User class.
User.java
#NoArgsConstructor
#AllArgsConstructor
#ToString
#Getter
#Setter
#Entity(name = "Users")
#ApiModel(description = "All details about user")
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "User_Type", discriminatorType= DiscriminatorType.STRING)
public class User implements Seriaalizable{
#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
#NoArgsConstructor
#AllArgsConstructor
#ToString
#Getter
#Setter
#Entity(name = "Players")
#DiscriminatorValue(value = "player")
#DiscriminatorOptions(force=true)
public class Player extends User {...}
Coach.java
#Entity(name = "Coaches")
#DiscriminatorValue(value = "coach")
#DiscriminatorOptions(force=true)
public class Coach extends User{
}
And here are DTO's:
CreateUserDto.java
public class CreateUserDto {...}
PlayerDto.java
public class PlayerDto extends CreateUserDto{...}
CoachDto.java
public class CoachDto extends CreateUserDto{
}
As I am very new to DAO and DTO pattern from error I am getting I assume that it is expected to have a model with #Entity called CreateUser so same name as DTO CreateUserDto? Or can I have the example what I did to have a User model and create a new CreateUserDto?
Thanks!
The error happens because you are treating a DTO as an entity.
Remove the JPA annotations from the DTOs and don't use those classes for connecting to the db.
You will convert the results from your queries from entities to DTO and vice-versa.
I would also suggest to have a look at Mapstruct for the creation of DTO. This will probably make it easier to separate the entities from the DTOs.

more name attributes in Table

Im my SQL Server Database I have 8 tables with the same structure.
Now I want to insert in selected tables with one Java class.
#Entity
#Table(name = "tbl_Prognosen") //here I want to put all table-Names
public class AZBNachricht { ...
is this possible?
It isn't possible to accomplish what you described.
The closest to code reuse at the entity class level would be to use a #MappedSuperclass class where you place all the shared column names, etc and then extend that for each table implementation with differing table names.
#MappedSuperclass
public abstract class AbstractStructure {
#Id
#GeneratedValue;
private Integer id;
private String column1;
private String column2;
}
#Entity
#Table(name = "table1")
public class Entity1 extends AbstractStructure {
}
// ... so on

Create criteria using Criteria Builder to query fields of concrete child class of abstract parent class

I working on a requirement where user enters a text and I need to show matching data on screen.
I am using EclipseLink as JPA provider.
Following is the code
#Entity
#Table(name="customer")
public class Customer{
private List<Address> addresses = new ArrayList<Address>();
//other code
}
#Entity
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "type")
#Table(name="address")
public abstract class Address{
private String name;
}
#Entity
public class PostalAddress extends Address{
private Contact number;
}
public class Contact{
private String number;
public Contact(String number){
this.number = number;
}
}
In DataBase I have table 'address' in which I have columns 'name' and 'number'.
I want to create a Predicate using CriteriaBuilder to search a specific value in table.
I have tried using
criteriabuiler.like(criteriabuiler.lower(root.join("addresses", JoinType.LEFT).<String>get("number")), searchString));
But it gives exception as
The attribute [msisdn] from the managed type [EntityTypeImpl#27575562:Address] is not present.
Can you please suggest a way to implement this thing?

Mapping Multiple Classes to a Table in Hibernate, Without a DTYPE Column

I have two hibernate classes: a base class, and an extended class that has additional fields. (These fields are mapped by other tables.)
For example, I have:
#Entity
#Table(name="Book")
public class A {
private String ID;
private String Name;
// ...
}
#Entity
#Table(name="Book")
public class B extends A {
public String node_ID;
// ...
}
public class Node {
public String ID; // maps to B.node_ID
// ...
}
How do I map this in Hibernate? The hibernate documentation states three types of inheritence configurations: one table per class, one table with a type column, and a join table -- none of which apply here.
The reason I need to do this is because class A is from generic framework that's reused over multiple projects, and class B (and Node) are extensions specific to one project -- they won't be used again. In the future, I may have perhaps a class C with a house_ID or some other field.
Edit: If I try the above pseudo-code configuration (two entities mapped to the same table) I get an error that the DTYPE column doesn't exist. The HQL has a "where DTYPE="A" appended.
This is possible by mapping the #DiscriminatorColumn and #DiscriminatorValue to the same values for both classes; this can be from any column you use that has the same data regardless of which type (not sure if it works with null values).
The classes should look like so:
#Entity
#Table(name="Book")
#Inheritance(strategy=InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name="published")
#DiscriminatorValue(value="true")
public class A {
private String ID;
private String Name;
// ...
}
#Entity
#Table(name="Book")
#DiscriminatorValue(value="true")
public class B extends A {
public String node_ID;
// ...
}
For anyone who got here like me and does not want to have the dtype column but instead want to use the same table for more than one entity as is I would recommend using this
Basically you can create a Base like this
#MappedSuperclass
public abstract class BaseBook<T extends BaseBook> {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", nullable = false)
private Long id;
... any other variables, getters + setters
}
#Entity
#Table(name= "book")
public class BookA extends BaseBook<BookA>{
//Default class no need to specify any variables or getters/setters
}
#Entity
#Table(name= "book")
public class BookB extends BaseBook<BookB>{
#Column(name = "other_field")
private String otherFieldInTableButNotMapedInBase
... Any other fields, getter/setter
}
From the above we have created base super class which does not have any entity or table mapping. We then create BookA to be default with the Entity + Table mapping. From there we can create other Entities all extending from BaseBook but pointing to one table

javax.persistence annotations and inheritance

I have 4 persistent classes which all have the same fields (exactly) the only 3 difference between them is 1) the class name, 2) the table name and 3) the data. i am aware that this might seem strange to some but trust me there is a good reason which i won't go into here.
now, i'm using hibernate annotations to configure my class which should work like so:
#Entity
#Table(name = "store")
public class Store
{
#Id
#Column(name = "unique_id")
protected String id;
#Column
protected String category;
...
}
.. and this does work, for a single stand-alone class, however there are many fields to map and i'd like to do it all in one hit for all four similar classes, ie:
public class StoreBase
{
#Id
#Column(name = "unique_id")
protected String id;
#Column
protected String category;
...
}
#Entity
#Table(name = "store1")
public class Store1 extends StoreBase
{}
#Entity
#Table(name = "store2")
public class Store2 extends StoreBase
{}
#Entity
#Table(name = "store3")
public class Store3 extends StoreBase
{}
#Entity
#Table(name = "store4")
public class Store4 extends StoreBase
{}
however when attempting this i get the following exception:
Caused by: org.hibernate.AnnotationException: No identifier specified for entity: package.entities.Store1
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:672)
at org.hibernate.cfg.AnnotationConfiguration.processArtifactsOfType(AnnotationConfiguration.java:546)
at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:291)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1292)
at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867)
i'm guessing this is because the super class is not being searched for the identifier?
is there a way to utilise inheritance in this context?
thanks, paul.
#MappedSuperclass
public class StoreBase
See docs for more info.
Have a look at #MappedSuperclass.

Categories