I'm developing a server application in jpa eclipselink.
This is my query that works fine when I run it in my sqlworkbench:
SELECT *
FROM `BuildingsTable` AS Buliding
LEFT JOIN ServiceCallsTable AS Calls ON ( Calls.`buildingId` = Buliding.id )
LEFT JOIN SchedualReviewsTable AS Review ON ( Review.`buildingId` = Buliding.id )
WHERE Buliding.id =1
I have 3 table BuildingsTable, ServiceCallsTable and SchedualReviewsTable
The buildingID variable found in Task class
ServiceCallsTable and SchedualReviewsTable extends from Task class
This is my code :
#Entity
#Table(name = "BuildingsTable")
public class Building extends Base{
#Column(name="description", nullable=false)
private String description;
#Column(name="address", nullable=false)
private String address;
#Column(name="constructYear", nullable=false)
private int constructYear;
#Column(name="constructorName", nullable=false)
private String constructorName;
#Column(name="amountParkings", nullable=false)
private int amountParkings;
#Column(name="amountWarehouses", nullable=false)
private int amountWarehouses;
#Column(name="childrenId", nullable=false)
// getters and setters
}
#MappedSuperclass
public abstract class Task extends Base{
#Column(name="description", nullable=false)
protected String description;
#OneToOne
#Column(name="buildingId", nullable=false)
protected long buildingId;
// getters and setters
}
#Entity
#Table(name = "ServiceCallsTable")
public class ServiceCall extends Task{
#Column(name="reporterId", nullable=false)
private long reporterId;
#Column(name="imageDescription", nullable=false)
private Text imageDescription;
#Column(name="status", nullable=false)
private int status;
// getters and setters
}
#Entity
#Table(name = "SchedualReviewsTable")
public class SchedualReview extends Task{
#Column(name="pivotDate", nullable=false)
private long pivotDate;
#Column(name="lastReviewDate", nullable=false)
private long lastReviewDate;
#Column(name="reviewDaysFrequancy", nullable=false)
private int reviewDaysFrequancy;
#Column(name="buildingFacilityTypeIds", nullable=false)
private List<Integer> buildingFacilityTypeIds;
#Column(name="name", nullable=false)
// getters and setters
}
How can I write this query in JPA?
Related
I am new to Hibernate. I am working on two entities as follows:
Entity 1 is as follows:
#Entity
#Table(name = "vm_user")
public class VmUser implements Serializable {
private static final long serialVersionUID = 1L;
#Column(name = "created_by")
private String createdBy;
#Column(name = "last_modified_by")
private String lastModifiedBy;
#Column(name = "created_date")
private Instant createdDate;
#Column(name = "last_modified_date")
private Instant lastModifiedDate;
#OneToOne
#JoinColumn(unique = true)
private User user; <--- HOW WILL I DENOTE THIS PRIMARY KEY OF VMUSER ENTITY ?
In the associated table in mysql i.e. vm_user, user_id is both primary key as well as foreign key which refers to id of user table associated with User entity.
Entity 2 is as follows:
#Entity
#Table(name = "my_entity")
public class MyEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Column(name = "created_by")
private String createdBy;
#Column(name = "last_modified_by")
private String lastModifiedBy;
#Column(name = "created_date")
private Instant createdDate;
#Column(name = "last_modified_date")
private Instant lastModifiedDate;
#ManyToOne
private A a;
#OneToOne
#JoinColumn(unique = true)
private B b;
In the associated table in mysql i.e. my_entity, primary key is a combination of id of a and id of b. I am not getting how to denote this in Hibernate entity MyEntity.
Regarding the same, I have gone through a few posts: Hibernate foreign key as part of primary key and JPA & Hibernate - Composite primary key with foreign key, but no getting idea how to do these two ?
The solution is #MapsId
For example
#Entity
#Table(name = "vm_user")
public class VmUser implements Serializable {
#Id
#Column(name = "user_id")
private Integer id;
#MapsId
#OneToOne
private User user;
You can also remove the #JoinColumn(unique = true) because #Id makes it unique already.
public class MyEntityPk implements Serializable {
private Integer aId;
private Integer bId;
// IMPORTANT: Override equals() and hashCode()
}
#IdClass(MyEntityPk.class)
#Entity
#Table(name = "my_entity")
public class MyEntity implements Serializable {
#Id
private Integer aId;
#Id
private Integer bId;
#MapsId("aId")
#ManyToOne
private A a;
#MapsId("bId")
#OneToOne
private B b;
Please find more information in the Hibernate documentation https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#identifiers-derived
You need to use #EmbeddedId and #MapsId ,
#Entity
#Table(name = "vm_user")
public class VmUser implements Serializable {
#Id
#Column(name = "user_id")
private Integer id;
#MapsId("user_id")
#OneToOne
private User user;
}
You can do the same thing for MyEntity as below,
#Embeddable
class BKey {
private int aId;
private int bId;
}
#Entity
#Table(name = "my_entity")
public class MyEntity implements Serializable {
#EmbeddedId
private BKey primaryKey;
#MapsId("aId")
#ManyToOne
private A a;
#MapsId("bId")
#OneToOne
#JoinColumn(unique = true)
private B b;
}
VM Users class
public class VmUser implements Serializable {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private long id;
#OneToOne
#JoinColumn(name="ID")
private Users user;
Users class
public class Users implements Serializable {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private long id;
#OneToOne(mappedBy="user")
private VmUser vmUser;
A class
#Entity
public class A implements Serializable {
#Id
private long id;
#OneToMany(mappedBy="a")
private List<MyEntity> myEntitys;
B Class
#Entity
public class B implements Serializable {
#Id
private long id;
#OneToMany(mappedBy="b")
private List<MyEntity> myEntitys;
MyEntity class
#Entity
public class MyEntity implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private MyEntityPK id;
#ManyToOne
#JoinColumn(name="ID1")
private A a;
#ManyToOne
#JoinColumn(name="ID2")
private B b;
MyEntityPK class
#Embeddable
public class MyEntityPK implements Serializable {
#Column(insertable=false, updatable=false)
private long id1;
#Column(insertable=false, updatable=false)
private long id2;
I want to create a view from two tables using annotations in java/JEE,
so after some researching I found that the only way to do it is using #Subselectannotation so I created 3 entities
the test entity:
#Table
#Entity
public class Test {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column
private String nom;
#Column
private String prenom;
#Column
private int age;
#Column
private String adresse;
#Column
private Date dateNaissance;
// getters and setters
}
The compte entity:
#Entity
public class Compte {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column
private long solde;
#Column
private long numero;
#Column
private String description;
// getters and setters
}
and the entity Compte_Test which has the same role as a view
#Entity
#Subselect("SELECT c2.id as idTest,c1.id as id,c1.solde as solde,c1.numero as numero, c2.nom as nom, c2.prenom as prenom FROM Compte c1 INNER JOIN Test c2 ON c1.id_test= c2.id")
#Synchronize({ "compte", "test" })
public class Compte_Test {
#Id
private long idCompte_Test;
#Column
private long idTest;
#Column
private long id;
#Column
private long solde;
#Column
private long numero;
#Column
private String nom;
#Column
private String prenom;
// getters and setters
}
I'm using spring data #Query annotation to get data from Compte_Test entity
#Query(value = "SELECT c from Compte_Test c ")
List<Compte_Test> fullTextSearch(Pageable pageable);
The problem is that it generates for me an error
org.postgresql.util.PSQLException: ERROR: column compte_tes0_.id_compte_test does not exist
Position : 8
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2440) ~[postgresql-42.2.5.jar:42.2.5]
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2183) ~[postgresql-42.2.5.jar:42.2.5]
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:308) ~[postgresql-42.2.5.jar:42.2.5]
i have been having hibernate circular dependency issues this are the class below:
#Entity
#JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="id")
public class Task extends DefaultEntity{
#ManyToOne
#JoinColumn(name = "cloth_model_id")
//#JsonIgnore
private ClothModel clothModel;
private String details;
private boolean completed;
#ManyToOne
#JoinColumn(name = "employee_id")
private Employee employee;
}
#Entity
#JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="id")
public class ClothModel extends DefaultEntity {
private ClothingType clothingType;
private int quantity;
private double amount;
#Transient
private String modelStructure;
private String savedUrl;
#Transient
//#JsonManagedReference
private List<Task> tasks = new ArrayList<>();
}
#MappedSuperclass
public class DefaultEntity implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(columnDefinition = "serial")
private long id;
#Column(name = "Time",columnDefinition= "TIMESTAMP WITH TIME ZONE")
#Temporal(TemporalType.TIMESTAMP)
private Date dateCreated;
i removed the getters and setters, so the code wouldn't be too much
When i apply the #JsonIdentityInfo or #JsonManagedReference, #JsonBackReference to both the ClothModel.class and Task.class, i notice that in the clothModel property in the Task.class will be ignored when i try writing a JSON to it, it acts like i am using a #Jsonignore annotation. Why is this and why isn't there a proper 100% working fix for Hibernate circular recursion.
I have a very large json to store and I divided that into following five entities and trying to store to h2 database using spring-data-jpa,inserting is working fine into database, but while fetching A object with A primary key Id, I am getting stackoverflow error, because there is circular dependency.
could someone help me to figure out what is the issue.
Top class
#Entity
#Table(name = "a")
#Data
public class A{
#Id
#Column(name = "a_id")
private String id;
#Column
private String name;
#Column
private String name2;
#Column
private String name3;
#Column
private String name4;
#Column
private String name5;
#OneToMany(cascade = CascadeType.ALL,mappedBy = "a",fetch =
FetchType.EAGER)
#JsonManagedReference
private List<B> b;
}
Second class
#Entity
#Table(name = "b")
#Data
public class B{
#Id
#Column(name = "bname")
private String bname;
#Column
private String bVersion;
#OneToMany(cascade = CascadeType.ALL,mappedBy = "b")
#JsonManagedReference
private List<C> cs;
#ManyToOne
#JoinColumn(name = "a_id")
#JsonBackReference
private A a;
}
Third class
#Entity
#Data
public class C{
#Id
#Column(name = "cname")
private String cName;
#Column
private String cVersion;
#OneToMany(cascade = CascadeType.ALL,mappedBy = "c")
#JsonManagedReference
private List<D> ds;
#ManyToOne
#JoinColumn(name = "bname")
#JsonBackReference
private B b;
}
Fourth class
#Entity
#Data
public class D{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="d_id")
private long id;
#Column
private String dName;
#Column
private String dName2;
#ElementCollection
#Column
private List<String> dNames;
#OneToMany(cascade = CascadeType.ALL,mappedBy = "d")
#JsonManagedReference
private List<E> e;
#ManyToOne
#JoinColumn(name = "cname")
#JsonBackReference
private C c;
}
Fifth class
#Entity
#Data
public class E{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "e_id")
private long id;
#Column
private String ename;
#Column
private String eName2;
#ManyToOne
#JoinColumn(name = "e_id")
#JsonBackReference
private E e;
}
I also faced the same problem and spent the whole day. Finally, I found its problem with the toString method generated by Lombok using #Data annotation.
Solution:
Override, toString method and write your own implementation. If you do not want to use toString then use #Getter and #Setter instead of #Data.
Why
Note: This occurs with bi-directional relationship.
Lets say I have two entity and having bi-directional relationship.
#data
Entity1{
#oneToMany
public List<Entity2> entity2s;
//Added by lombok while using #Data
#Generated
public String toString() {
return "entity2s=" + this.getEntity2s() + ")";
}
}
#data
Entity2{
#ManytoOne
public Entity1 entity1;
//Added by lombok while using #Data
#Generated
public String toString() {
return "entity1=" + this.getEntity1() + ")";
}
}
In above example, toString()(called by JPA) of Entity1 calles toString() of Entity2 and toString() of Entity2 calls toString() of Entity1. And that is how circular reference is building.
Note: The same goes to hashCode method.
Here is a some reference links,
https://github.com/rzwitserloot/lombok/issues/1007
https://interviewbubble.com/stackoverflow-tostring-method-when-using-lombok/
I have two classes
Alocacao and Responsavel
I have a 1:n
Responsavel.class
#Entity
#Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
#Table(name="Responsavel")
public class Responsavel {
#Id
#Column(name="idResp")
private int idResp;
#Column(name="nomeResp")
private String nomeResp;
#Column(name="emailResp")
private String email;
#ManyToOne(fetch=FetchType.EAGER)
#JoinColumn(name="idGrupResp")
private GrupoResponsavel grupo;
#Column(name="idPovUser")
private int povUser;
#ManyToMany(mappedBy="responsavel", fetch=FetchType.EAGER)
private List<TarefaBackLog> tarefa;
public Responsavel() {
super();
}
//getters and setters
Alocacao.class
#Entity
#Table(name = "responsavel_alocacao")
public class Alocacao {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "idRespAloc")
private int idAlocacao;
#ManyToOne
#JoinColumn(name="idResponsavel", referencedColumnName="idResp")
private Responsavel idResponsavel;
#JoinColumn(name="idPeriodo")
private PeriodoPov idPeriodo;
#Column(name="Alocacao")
private double alocacao;
//getters and setters
But when I try to get all the Alocacao objects with "findAll()", it brings me null values to idPeriodo and idResponsavel.. any ideas?
Thanks