I have two entity class Category and Events.I need to join both the tables and fetch all records which matching the given condition
My sql query for this
SELECT * FROM category c inner join `events` e on e.category_i=c.category_id where c.parent_category_id=1;
How i can convert this sql query to hql and fetch the data ? I tried below but not getting the result ? Am very new to hibernate
Events entity class for hibernate mapping
import java.io.Serializable;
import java.util.Date;
import javax.persistence.*;
/**
* The persistent class for the user database table.
*
*/
#Entity
#Table(name = "events")
public class Events implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "event_id")
private int eventId;
#Column(name = "event_name")
private String eventName;
#Column(name = "event_description")
private String eventDescription;
#Column(name = "category_i")
private Integer categoryI;
public Integer getCategoryI() {
return categoryI;
}
public void setCategoryI(Integer categoryI) {
this.categoryI = categoryI;
}
#Column(name = "is_trending_event")
private Integer isTrendingEvent;
#Column(name = "image_url")
private String imageUrl;
private Integer status;
#Column(name = "created_date")
#Temporal(javax.persistence.TemporalType.DATE)
private Date createdDate;
#Column(name = "last_updated_date")
#Temporal(javax.persistence.TemporalType.DATE)
private Date lastUpdatedDate;
public Date getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
public Date getLastUpdatedDate() {
return lastUpdatedDate;
}
public void setLastUpdatedDate(Date lastUpdatedDate) {
this.lastUpdatedDate = lastUpdatedDate;
}
public int getEventId() {
return eventId;
}
public void setEventId(int eventId) {
this.eventId = eventId;
}
public String getEventName() {
return eventName;
}
public void setEventName(String eventName) {
this.eventName = eventName;
}
public String getEventDescription() {
return eventDescription;
}
public void setEventDescription(String eventDescription) {
this.eventDescription = eventDescription;
}
public Integer getIsTrendingEvent() {
return isTrendingEvent;
}
public void setIsTrendingEvent(Integer isTrendingEvent) {
this.isTrendingEvent = isTrendingEvent;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
}
Category entity
import java.io.Serializable;
import java.util.Date;
import javax.persistence.*;
/**
* The persistent class for the user database table.
*
*/
#Entity
#Table(name = "category")
public class Category implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "category_id")
private int categoryId;
#Column(name = "category_name")
private String categoryName;
#Column(name = "parent_category_id")
private Integer parentCategoryId;
#Column(name = "created_date")
#Temporal(javax.persistence.TemporalType.DATE)
private Date createdDate;
#Column(name = "last_updated_date")
#Temporal(javax.persistence.TemporalType.DATE)
private Date lastUpdatedDate;
#ManyToOne
#JoinTable(name="events", joinColumns = #JoinColumn(name="category_i"))
private Events events;
public int getCategoryId() {
return categoryId;
}
public void setCategoryId(int categoryId) {
this.categoryId = categoryId;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public Integer getParentCategoryId() {
return parentCategoryId;
}
public void setParentCategoryId(Integer parentCategoryId) {
this.parentCategoryId = parentCategoryId;
}
public Date getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
public Date getLastUpdatedDate() {
return lastUpdatedDate;
}
public void setLastUpdatedDate(Date lastUpdatedDate) {
this.lastUpdatedDate = lastUpdatedDate;
}
}
Fetch category method
public List<Object[]> getCategoryList(int id) throws SQLException, ClassNotFoundException, IOException {
List<Object[]> groupList = null;
try {
Session session = sessionFactory.getCurrentSession();
Query query = session.createQuery("select e from Category e inner join e.events where e.parentCategoryId=1");
//query.setParameter("id", id);
groupList = query.list();
} catch (Exception e) {
}
return groupList;
}
You need to think in terms of Java objects when using ORM tools.
From your question I think the query that you're trying to write will look something like:
public List<Category> getCategoryList(int id) {
List<Category> groupList;
Session session = sessionFactory.getCurrentSession();
Query query = session.createQuery("select c from Category c join fetch c.events where c.parentCategory.categoryId = 1");
//query.setParameter("id", id);
groupList = query.list();
return groupList;
}
One of the benefits of using an ORM is that it works out the full join query for you.
For this to work you need to update your class model as follows:
import java.io.Serializable;
import java.util.Date;
import javax.persistence.*;
#Entity
#Table(name = "events")
public class Event implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "event_id")
private int eventId;
#Column(name = "event_name")
private String eventName;
#Column(name = "event_description")
private String eventDescription;
#ManyToOne
#JoinColumn(name = "category_i")
private Category category;
#Column(name = "is_trending_event")
private Integer isTrendingEvent;
#Column(name = "image_url")
private String imageUrl;
private Integer status;
#Column(name = "created_date")
#Temporal(javax.persistence.TemporalType.DATE)
private Date createdDate;
#Column(name = "last_updated_date")
#Temporal(javax.persistence.TemporalType.DATE)
private Date lastUpdatedDate;
...
}
and
import java.io.Serializable;
import java.util.Date;
import javax.persistence.*;
#Entity
#Table(name = "category")
public class Category implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "category_id")
private int categoryId;
#Column(name = "category_name")
private String categoryName;
#ManyToOne
#JoinColumn(name="parent_category_id")
private Category parentCategory;
#Column(name = "created_date")
#Temporal(javax.persistence.TemporalType.DATE)
private Date createdDate;
#Column(name = "last_updated_date")
#Temporal(javax.persistence.TemporalType.DATE)
private Date lastUpdatedDate;
#OneToMany(mappedBy="category")
private List<Event> events;
...
}
Hibernate is about mapping objects and the relations, however you are mapping simple id fields.
In your Events class you have the followingL
#Entity
#Table(name = "events")
public class Events implements Serializable {
#Column(name = "category_i")
private Integer categoryI;
}
However it should be a Category instead of an Integer.
#Entity
#Table(name = "events")
public class Events implements Serializable {
#ManyToOne
#Column(name = "category_i")
private Category category;
}
Then in your Category you should add the mappedBy field to the #ManyToOne on the events field and remove the #JoinColumn.
#Entity
#Table(name = "category")
public class Category implements Serializable {
#OneToMany(mappedBy="category")
private Events events;
}
The same applies to the parentCategoryId of the Category class.
Now that you have your mapping corrected you should be able to write the query as you wanted to.
This query should do the job:
from Category as c
inner join c.events as e
where c.parentCategoryId = 1
Plus you seem to have a typo (missing "d" at the end) here:
#JoinColumn(name="category_i"))
Ty this below code
public List<Object[]> getCategoryList(int id) throws SQLException, ClassNotFoundException, IOException {
Session session = sessionFactory.getCurrentSession();
return session.createCriteria(Catagory.class)
.setFetchMode("events", FetchMode.JOIN)
.add(Restrictions.eq("parentCatagoryId", 1))
.list();
}
Hope this stuff works.
Related
I have a relation between a parent and child table in which, the parent table has a single primary key and the child table has a composite primary key. However only one of the columns in the child table is referenced to the parent table.
My hibernate classes are wired up as such:
Parent Table
#Entity
#Table(name = "snippet")
public class SnippetEntity implements Serializable{
private static final long serialVersionUID = -3220451853395334879L;
#Id
#Column(name = "snpt_id", nullable=false, updatable=false)
#JsonBackReference
private String snippetId;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "cretn_ts")
private Date creationTimeStamp;
#Column(name = "cretn_user_id")
private String creationUserId;
public String getSnippetId() {
return snippetId;
}
public void setSnippetId(String snippetId) {
this.snippetId = snippetId;
}
public Date getCreationTimeStamp() {
return creationTimeStamp;
}
public void setCreationTimeStamp(Date creationTimeStamp) {
this.creationTimeStamp = creationTimeStamp;
}
public String getCreationUserId() {
return creationUserId;
}
public void setCreationUserId(String creationUserId) {
this.creationUserId = creationUserId;
}
#Override
public String toString() {
return "SnippetEntity{" +
"snippetId='" + snippetId + '\'' +
'}';
}
}
Child Table
#Entity
#Table(name = "snippet_detail")
public class SnippetDetailEntity implements Serializable {
private static final long serialVersionUID = -7470223455753164243L;
#Id
#Column(name = "lang_cd", nullable=false, updatable=false)
private String language;
#Column(name = "snpt_type_cd")
private String snippetType;
#Column(name = "snpt_desc")
private String snippetDescription;
#Column(name = "snpt_txt")
private String snippetText;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "cretn_ts")
private Date creationTimeStamp;
#Column(name = "cretn_user_id")
private String creationUserId;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "updt_ts")
private Date updatedTimeStamp;
#Column(name = "updt_user_id")
private String updatedUserId;
#ManyToOne
#JoinColumn(name="snpt_id")
#JsonManagedReference
private SnippetEntity snippetEntity;
public SnippetDetailEntity() {}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public String getSnippetType() {
return snippetType;
}
public void setSnippetType(String snippetType) {
this.snippetType = snippetType;
}
public String getSnippetDescription() {
return snippetDescription;
}
public void setSnippetDescription(String snippetDescription) {
this.snippetDescription = snippetDescription;
}
public String getSnippetText() {
return snippetText;
}
public void setSnippetText(String snippetText) {
this.snippetText = snippetText;
}
public Date getCreationTimeStamp() {
return creationTimeStamp;
}
public void setCreationTimeStamp(Date creationTimeStamp) {
this.creationTimeStamp = creationTimeStamp;
}
public String getCreationUserId() {
return creationUserId;
}
public void setCreationUserId(String creationUserId) {
this.creationUserId = creationUserId;
}
public Date getUpdatedTimeStamp() {
return updatedTimeStamp;
}
public void setUpdatedTimeStamp(Date updatedTimeStamp) {
this.updatedTimeStamp = updatedTimeStamp;
}
public String getUpdatedUserId() {
return updatedUserId;
}
public void setUpdatedUserId(String updatedUserId) {
this.updatedUserId = updatedUserId;
}
public SnippetEntity getSnippetEntity() { return snippetEntity; }
public void setSnippetEntity(SnippetEntity snippetEntity) { this.snippetEntity = snippetEntity; }
#Override
public String toString() {
return "SnippetDetailEntity{" +
"language='" + language + '\'' +
", snippetType='" + snippetType + '\'' +
", snippetDescription='" + snippetDescription + '\'' +
", snippetText='" + snippetText + '\'' +
", creationTimeStamp=" + creationTimeStamp +
", creationUserId='" + creationUserId + '\'' +
", updatedTimeStamp=" + updatedTimeStamp +
", updatedUserId='" + updatedUserId + '\'' +
", snippetEntity=" + snippetEntity +
'}';
}
}
The call to get all snippet_detail is:
List<SnippetDetailEntity> snippetEntities = dbService.getAll(SnippetDetailEntity.class);
public <T> List<T> getAll(Class<T> clazz) {
return getSession().createCriteria(clazz).list();
}
There are 378 records in snippet_detail. So, my problem is, when I do a list to get all rows from snippet_detail I get two unique records (the first two that match the primary keys on this table) from snippet_detail and these records are duplicated multiple times. The total number of records are still 378, but these 378 records are made of the two records duplicated multiple times. What I am totally confused about and I admit this maybe due to my understanding of hibernate is why is this happening? I have read through a lot of posts and they all talk about hibernate doing an outer join. Is there something wrong I am doing? If so, what do I do to fix this?
UPDATE:
Reading through some more blogs and post I realized that I have a composite key in my snippet_detail and the way to handle that with hibernate it to use the #Embeddable annotations. I created a #Embeddable class that has the snpt_id and lang_cd. I modified my snippet_detail entity class to use the #Embeddable class. I also moved the #ManyToOne join into the #Embeddable class because I figured this is where I need to specify the join condition (i.e. between the snpt_id of the snippet_detail and the snpt_id of the snippet table.
Now, the fetch works fine, but when I insert into the snippet_detail I get an hibernate error that says it can't perform the insert because I violate the referential key constraint. In the classes that I have in my original post, the #ManyToOne was within the child class and in that case the insert to the child table would insert a record in the parent snippet table if the record did not already exist in the snippet table.
My parent table class is same as above. The new #Embeddable class and my child classes are modified as:
#Embeddable
public class SnippetDetailPrimaryEntity implements Serializable {
#ManyToOne
#JoinColumn(name = "snpt_id")
private SnippetEntity snippetEntity;
#Column(name = "lang_cd")
private String language;
}
#Entity
#Table(name = "snippet_detail")
public class SnippetDetailEntity implements Serializable {
#EmbeddedId
private SnippetDetailPrimaryEntity snippetDetailPrimaryEntity;
#Column(name = "snpt_type_cd")
private String snippetType;
#Column(name = "snpt_desc")
private String snippetDescription;
#Column(name = "snpt_txt")
private String snippetText;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "cretn_ts")
private Date creationTimeStamp;
#Column(name = "cretn_user_id")
private String creationUserId;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "updt_ts")
private Date updatedTimeStamp;
#Column(name = "updt_user_id")
private String updatedUserId;
}
So, for a parent child relation where the parent table has a single primary key, child has a composite key and when one of the child's key has a referential constraint back to the parent, this is what worked for me.
Parent
#Entity
#Table(name = "snippet")
public class SnippetEntity implements Serializable{
private static final long serialVersionUID = -3220451853395334879L;
#Id
#Column(name = "snpt_id", nullable=false, updatable=false)
private String snippetId;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "cretn_ts")
private Date creationTimeStamp;
#Column(name = "cretn_user_id")
private String creationUserId;
}
Child's composite key as Embeddable:
#Embeddable
public class SnippetDetailPrimaryEntity implements Serializable{
#Column(name = "snpt_id")
private String snippetId;
#Column(name = "lang_cd")
private String language;
}
Child
#Entity
#Table(name = "snippet_detail")
public class SnippetDetailEntity implements Serializable {
private static final long serialVersionUID = -7470223455753164243L;
#EmbeddedId
private SnippetDetailPrimaryEntity snippetDetailPrimaryEntity;
#Column(name = "snpt_type_cd")
private String snippetType;
#Column(name = "snpt_desc")
private String snippetDescription;
#Column(name = "snpt_txt")
private String snippetText;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "cretn_ts")
private Date creationTimeStamp;
#Column(name = "cretn_user_id")
private String creationUserId;
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "updt_ts")
private Date updatedTimeStamp;
#Column(name = "updt_user_id")
private String updatedUserId;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name="snpt_id", insertable = false, updatable = false)
private SnippetEntity snippetEntity;
}
I have Class Customer ,User , Customer has property manager of user class
Class Customer {
/** The manager. */
#ManyToOne(optional = false, cascade = {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE})
#JoinColumn(name = "MANAGER")
#JsonSerialize(using = EntitySerializer.class)
#JsonDeserialize(using = UserDeserializer.class)
private User manager;
}
-------------------------------------
Class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator = User.TABLE_NAME + "_SEQUENCE")
#SequenceGenerator(name = User.TABLE_NAME + "_SEQUENCE", sequenceName = User.TABLE_NAME + "_SEQ")
#Column(name = FIELD_ID, nullable = false)
#SuppressWarnings("PMD.ShortVariable")
private Integer id;
#Override
public Integer getId() {
return id;
}
#Override
public void setId(final Integer newId) {
//System.out.println("setID");
id = newId;
}
}
Now when i am trying to create criteria
final Criteria criteria = getSession().createCriteria(Customer.class);
criteria.add(Restrictions.ilike("manager", "%"+searchTerm+"%"))
It throwing Error :-
org.hibernate.PropertyAccessException: could not get a field value by reflection getter of com.User.id
Caused by:
java.lang.IllegalArgumentException: Can not set java.lang.Integer field com.User.id to java.lang.String
**Id field is integer **
Could you please change the following:
final Criteria criteria = getSession().createCriteria(Customer.class); criteria.add(Restrictions.ilike("manager", "%"+searchTerm+"%"))
by the following:
final Criteria criteria = getSession().createCriteria(Customer.class); criteria.add(Restrictions.ilike("manager.name", "%"+searchTerm+"%"))
LIKE clause is applicable to text column only.
this code to used
return this.sessionFactory.getCurrentSession()
.createCriteria(UserTraining.class)
.add(Restrictions.eq("userProfile.userId", userId))
.list();
You used this annotation to error remove
#Table(name="user_training")
#Entity
public class UserTraining {
#Id
#GeneratedValue
#Column(name="id")
private int id;
//Generate getter setter of id
/*
#Column(name="user_id")
private int userId;
*/
#JsonIgnore
#ManyToOne(cascade = {CascadeType.ALL})
#JoinColumn(name = "user_id")
private UserProfile userProfile;
public UserProfile getUserProfile() {
return userProfile;
}
public void setUserProfile(UserProfile userProfile) {
this.userProfile = userProfile;
}
#OneToOne
#JoinColumn(name = "training_id")
private Training training;
#Column(name="view_count")
private int viewCount;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Training getTraining() {
return training;
}
public void setTraining(Training training) {
this.training = training;
}
public int getViewCount() {
return viewCount;
}
public void setViewCount(int viewCount) {
this.viewCount = viewCount;
}
}
I have a category table.In which first 5 are main category and
others are sub category.
I need to fetch the sub categories of first 5 main category so i have found the sql query
SELECT m.category_id,m.category_name AS 'Parent',
e.category_name AS 'Sub'
FROM category e
INNER JOIN category m ON m.category_id = e.parent_category_id
ORDER BY Parent
The query is joining the same table itself.and am getting the result given below
Result
How can i convert the SQL query to HQL and return the data like above image to user in
standard json format ?
FetchSubCategory
import java.io.Serializable;
import java.util.Set;
import javax.persistence.*;
#Entity
#Table(name = "category")
public class FetchSubCategory implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "category_id")
private Integer categoryId;
#Column(name = "category_name")
private String categoryName;
#ManyToOne(cascade = {CascadeType.ALL})
#JoinColumn(name = "parent_category_id")
private FetchSubCategory parent;
#OneToMany(mappedBy = "parent")
private Set<FetchSubCategory> subCategory;
public Integer getCategoryId() {
return categoryId;
}
public void setCategoryId(Integer categoryId) {
this.categoryId = categoryId;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public FetchSubCategory getParent() {
return parent;
}
public void setParent(FetchSubCategory parent) {
this.parent = parent;
}
public Set<FetchSubCategory> getSubCategory() {
return subCategory;
}
public void setSubCategory(Set<FetchSubCategory> subCategory) {
this.subCategory = subCategory;
}
}
Method
public Set<FetchSubCategory> fetchSubCategory() throws SQLException, ClassNotFoundException, IOException {
Set<FetchSubCategory> groupList = null;
try {
Session session = sessionFactory.getCurrentSession();
Query query = session.createQuery("SELECT m.categoryName AS 'Parent', e.categoryName AS 'Sub' FROM FetchSubCategory e INNER JOIN FetchSubCategory m ORDER BY Parent");
groupList = (Set<FetchSubCategory>) query.list();
} catch (Exception e) {
e.printStackTrace();
}
return groupList;
}
Can any one please correct my mistake and tell me how to fetch result like above image?
This stuff will solve your problem
#Entity
#Table(name = "category")
public class FetchSubCategory implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "category_id")
private Integer categoryId;
#Column(name = "category_name")
private String categoryName;
#NotFound(action = NotFoundAction.IGNORE)
#ManyToOne
#JsonIgnore
#JoinColumn(name = "parent_category_id")
private FetchSubCategory mainCategory;
#JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY)//Avoiding empty json arrays.objects
#OneToMany(mappedBy = "mainCategory", fetch = FetchType.EAGER)
private List<FetchSubCategory> subCategory;
public Integer getCategoryId() {
return categoryId;
}
public void setCategoryId(Integer categoryId) {
this.categoryId = categoryId;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public FetchSubCategory getMainCategory() {
return mainCategory;
}
public void setMainCategory(FetchSubCategory mainCategory) {
this.mainCategory = mainCategory;
}
public List<FetchSubCategory> getSubCategory() {
return subCategory;
}
public void setSubCategory(List<FetchSubCategory> subCategory) {
this.subCategory = subCategory;
}
Get your sub categories
public List<FetchSubCategory> fetchSubCategory() throws SQLException, ClassNotFoundException, IOException {
List<FetchSubCategory> groupList = null;
try {
Session session = sessionFactory.getCurrentSession();
Query query = session.createQuery("select distinct e FROM FetchSubCategory e INNER JOIN e.subCategory m ORDER BY m.mainCategory");
groupList = query.list();
} catch (Exception e) {
e.printStackTrace();
}
return groupList;
}
For self join as in your case, below will work for you.
#ManyToOne(cascade={CascadeType.ALL})
#JoinColumn(name = "parent_category_id")
private FetchSubCategory parent;
#OneToMany(mappedBy = "parent")
private Set<FetchSubCategory> subCategory;
FetchSubCategory entity class, we defined two attributes: FetchSubCategory parent and Set<FetchSubCategory> subCategory. Attribute parent is mapped with #ManyToOne annotation and subordinates is mapped with #OneToMany. Also within #OneToMany attribute we defined mappedBy="parent" making parent as the relationship owner and thus which manages the foreign relationship within table.
Also the annotation #JoinColumn is defined on parent making it the relationship owner. #JoinColumn defines the joining column which in our case is parent_category_id.
Hi I am new to this world.
I am making my own application with spring jpa hibernate.
I have an entity class. It works generally but it duplicates attributes.
My code look like this:
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.validation.constraints.NotNull;
#Entity
public class Event {
#Id
#GeneratedValue
private Integer id;
public Integer getId() {
return id;
}
#Column(nullable = false)
public void setId(Integer id) {
this.id = id;
}
/*------------------------------ title ------------------------*/
private String title;
#Column(nullable = false)
public String getTitle() {
return title;
}
#Column(nullable = false)
public void setTitle(String title) {
this.title = title;
}
/* [Note] I have two extra ids : event_id, eventId
- so these are not the case of the duplication. */
/*------------------- event_id -----------------------------*/
private String event_id;
public String getEvent_id() {
return event_id;
}
public void setEvent_id(String event_id) {
this.event_id = event_id;
}
/*-------------- eventId -------------------------------------*/
#Column(unique = true)
private String eventId;
public String getEventId() {
return eventId;
}
public void setEventId(String eventId) {
this.eventId = eventId;
}
/*------------------------------ publishedDate ------------------------------------------*/
private String publishedDate;
public String getPublishedDate() {
return publishedDate;
}
#Column(nullable = false)
public void setPublishedDate(String publishedDate) {
this.publishedDate = publishedDate;
}
/*--------------------------------- endTime -----------------------------------*/
private String endTime;
public String getEndTime() {
return endTime;
}
#Column(nullable = false)
public void setEndTime(String endTime) {
this.endTime = endTime;
}
/*-------------------------------- user ------------------------------------------*/
#ManyToOne
#JoinColumn(name="user_id")
private User user;
public User getUser() {
return user;
}
#Column(nullable = false)
public void setUser(User user) {
this.user = user;
}
Then when I check JPA diagram, it has duplication of several attributes.
I added my JPA diagram image(the red parts are duplicated)
This is my very first application with java programming.
so please understand, even I read documentation of the spring jpa,
It is difficult to figure out what exactly I did wrong in the code.
Any ideas? Thanks in advance.
The problem is that JPA expects either field level annotations or accessor (getters/setters) annotations. However you are using both, which basically isn't allowed. Remove all he annotations from the accessors and only put them on the fields.
Small hint on Java programming (styling) put your fields on top of the classes instead of between the accessors.
#Entity
public class Event {
#Id
#GeneratedValue
private Integer id;
#Column(unique = true)
private String eventId;
private String event_id;
#Column(nullable = false)
private String title;
#Column(nullable = false)
private String publishedDate;
#Column(nullable = false)
private String endTime;
#ManyToOne
#JoinColumn(name="user_id")
#Column(nullable = false)
private User user;
// Getters / Setters omitted
}
Remove the annotations from the accessors, also do you really want to set the id? I would expect not, so you might want to remove the setId method.
As mentioned in comments, your problem is that you are using two annotations for the same attribute, first in the field and then in its getter/setter, so you have to use only one of them, for example:
#Id
#GeneratedValue
private Integer id;
public Integer getId() {
return id;
}
#Column(nullable = false)
public void setId(Integer id) {
this.id = id;
}
Should be:
#Id
#GeneratedValue
private Integer id;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
And it's wrong to usnnotations here with both getter and setter:
#Column(nullable = false)
public String getTitle() {
return title;
}
#Column(nullable = false)
public void setTitle(String title) {
this.title = title;
}
Note:
So in order to avoid this, you have to choose between:
Using annotations with the field.
And using them with its setter.
Spring Boot 2.0.0.M5, JPA, Hibernate 5.2.11.Final
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "auto_gen")
#SequenceGenerator(name = "auto_gen", sequenceName = "customer_id_seq", allocationSize=1)
#Column(name = "id")
private Long id;
This is a working sample:
package hello;
import org.hibernate.annotations.Type;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
#Entity
#Table(name = "customer")
public class Customer {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "auto_gen")
#SequenceGenerator(name = "auto_gen", sequenceName = "customer_id_seq", allocationSize = 1)
#Column(name = "id")
private Long id;
#Column(name = "first_name")
//#Type(type="org.hibernate.type.StringType")
private String firstName;
#Column(name = "last_name")
//#Type(type="org.hibernate.type.StringType")
private String lastName;
protected Customer() {
}
public Customer(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
#Override
public String toString() {
return String.format("Customer[id=%d, firstName='%s', lastName='%s']", id, firstName, lastName);
}
}
Here is another case of this ERROR:
21:22:15,881 ERROR [SessionFactoryImpl] Error in named query: ch.software.gvs.TroubleNotification_DeviceType.byType org.hibernate.QueryException:
could not resolve property: type of: ch.ildsoftware.gvs.TroubleNotification_DeviceType
[select d.id from ch.ildsoftware.gvs.TroubleNotification_DeviceType d where d.type = :type]
I have following setting:
queries.xml:
<named-query name="ch.ildsoftware.gvs.TroubleNotification_DeviceType.byType">
<query>
select t.id from TroubleNotification_DeviceType t where t.type = :type
</query>
</named-query>
TroubleNotification_DeviceType.java
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name = "tblgwTroubleNotification_ADSTyp")
public class TroubleNotification_DeviceType implements Serializable {
private static final long serialVersionUID = 1L;
private TroubleNotification id;
private DeviceType type;
private String createdBy;
private String createdDate;
public TroubleNotification_DeviceType()
{}
public TroubleNotification_DeviceType(TroubleNotification id, DeviceType type) {
this.id = id;
this.type = type;
}
#Id
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "IDgwTroubleNotification", nullable = false)
public TroubleNotification getId() {
return id;
}
public void setId(TroubleNotification id) {
this.id = id;
}
#Id
#Column(name = "ADSTypID", nullable = false)
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "GeraeteTypID", nullable = false)
public DeviceType getType() {
return type;
}
public void setType(DeviceType type) {
this.type = type;
}
#Column(name = "Created", nullable = false)
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
#Column(name = "CreatedDate", nullable = false)
public String getCreatedDate() {
return createdDate;
}
public void setCreatedDate(String createdDate) {
this.createdDate = createdDate;
}
}
I suspect there might be something wrong with the #Column and #JoinColumn annotation. It's just that the column-name I join with, is from a view which aliases the column name.
But maybe something else is wrong. I'm rather new to this.
snippet out of DeviceType:
private static final long serialVersionUID = 1L;
private Integer id;
private String name;
....
#Id
#Column(name = "GeraeteTypID", nullable = false)
public Integer getId()
{
return this.id;
}
In other classes the reference would be like this, and work well (yet the column name is identical):
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "GeraeteTypID", nullable = false)
public DeviceType getType()
{
return this.type;
}
snippet out of an EJB:
#Override
#SuppressWarnings("unchecked")
public List<TroubleNotification> getTroubleNotificationByDeviceType(DeviceType aType)
{
// first get all IDgwTroubleNotification for ADSTypID
Query idSet = gvsData.createNamedQuery(
TroubleNotification_DeviceType.class.getName() + ".byType");
idSet.setParameter("type", aType);
List<TroubleNotification> idSetResult = idSet.getResultList();
final List<TroubleNotification> troubleNotificationResult = new ArrayList<TroubleNotification>();
for (int i = 0; i < idSetResult.size(); i++) {
// get all Notification for IDgwTroubleNotification
Query notificationById = gvsData.createNamedQuery(
TroubleNotification.class.getName() + ".byId");
notificationById.setParameter("id", idSetResult.get(i));
troubleNotificationResult.add((TroubleNotification) notificationById.getResultList());
}
return troubleNotificationResult;
}
Thank you for your help!
I discovered that my DB mapping was not at all proper. I have an n:m relation, which doesn't seem like an easy one with hibernate. But this was very helpful:
Hibernate Many-To-Many Revisited
But that was still not solving the problem. And I discovered that I have composite primary keys, that the primary keys of two tables are mapped in the n:m table. Another not so easy setting. So I followed this thread: Mapping ManyToMany with composite Primary key and Annotation:
The configuration from the second link, together with an SQL statement according to the second strategy in the first link works.