Hibernate: set condition to multiple level childs - java

I have a question about hibernate query. I am using hiberate 5.3.10.
First of all, I have domain Parent.java, ParentAlert.java and ParentAlertDetail.java like follow:
Parent:
public class Parent {
private String parentId;
private List<ParentAlert> parentAlerts;
#Id
#Column(name = "Parent_id", length = 12)
public String getParentId() {
return parentId;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
#OneToMany(
targetEntity = ParentAlert.class,
mappedBy = "parentAlert",
fetch = FetchType.LAZY)
public List<ParentAlert> getParentAlerts() {
return parentAlerts;
}
public void setParentAlerts(List<ParentAlert> parentAlerts) {
this.parentAlerts = parentAlerts;
}}
ParentAlert:
public class ParentAlert {
private String parentAlertID;
private Parent parent;
private Collection<ParentAlertDetail> parentAlertDetails;
private String status;
#Id
#Column(name = "Parent_Alert_ID", length = 12)
#NotEmpty
public String getParentAlertID() {
return parentAlertID;
}
public void setParentAlertID(String parentAlertID) {
this.parentAlertID = parentAlertID;
}
#OneToOne(targetEntity = Parent.class, fetch = FetchType.LAZY)
#JoinColumn(name = "Parent_id")
public Parent getParent() {
return parent;
}
public void setParent(Parent parent) {
this.parent = parent;
}
#OneToMany(targetEntity = ParentAlertDetail.class, mappedBy = "id.parentAlert", fetch = FetchType.LAZY, cascade = {
CascadeType.ALL })
public Collection<ParentAlertDetail> getParentAlertDetails() {
return parentAlertDetails;
}
public void setParentAlertDetails(Collection<ParentAlertDetail> parentAlertDetails) {
this.parentAlertDetails = parentAlertDetails;
}
#Column(name = "status", nullable = false, length = 1)
public String getStatus() {
return this.status;
}
public void setStatus(String status) {
this.status = status;
}}
ParentAlertDetail
public class ParentAlertDetail{
private ParentAlertDetailID id;
private String desc;
private String status;
#EmbeddedId
#AttributeOverrides(value = { #AttributeOverride(name = "parentAlert", column = #Column(name = "Parent_Alert_Id")),
#AttributeOverride(name = "parentAlertDetailId", column = #Column(name = "Parent_Alert_Detail_id")) })
public ParentAlertDetailID getId() {
return id;
}
public void setId(ParentAlertDetailID id) {
this.id = id;
}
#Column(name = "desc", length = 100)
public String getDesc() {
return this.desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
#Column(name = "Status", length = 1)
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}}
ParentAlertDetailID
public class ParentAlertDetailID{
private Integer parentAlertDetailId;
private ParentAlert parentAlert;
#Column(name = "Parent_Alert_Detail_id")
#NotEmpty
public Integer getParentAlertDetailId() {
return parentAlertDetailId;
}
public void setParentAlertDetailId(Integer parentAlertDetailId) {
this.parentAlertDetailId = parentAlertDetailId;
}
#ManyToOne(targetEntity = ParentAlert.class, fetch = FetchType.LAZY)
#JoinColumn(name = "Parent_Alert_ID", nullable = true)
public ParentAlert getParentAlert() {
return parentAlert;
}
public void setParentAlert(ParentAlert parentAlert) {
this.parentAlert = parentAlert;
} }
I would like to filter the parentAlert.status = 'A' and parentAlertDetail.status = 'A'.
The query is
String sql = "SELECT distinct parent FROM Parent parent"
+ " LEFT OUTER JOIN fetch parent.parentAlerts patientAlert"
+ " LEFT OUTER JOIN patientAlert.patientAlertDetails patientAlertDetail"
+ " WHERE (patientAlert.status ='A' or patientAlert.status is null) "
+ " and (patientAlertDetail.status ='A' or patientAlertDetail.status is null)";
Query query = getCurrentSession().createQuery(sql);
List<Parent> resultList = query.getResultList();
However, I found that the records under PatientAlertDetail cannot be filter (mean that patientAlertDetail.status = 'I' records selected also)
May I ask anything wrong in my query or domain?
Also, is it possible to fetch all tables in parent domain without using fetch in the query? This is because I have more than one child domain in Parent (e.g. ParentContact etc)
Thanks.

Related

Hibernate error: Illegal Attempt to deference collection

Hello I have a one to many relationship between a reservation and rooms and its unidirectional. A reservation might have one to several rooms. Now I'm trying to search if a room is available based on certain dates, and type of room(i.e a king or queen).
My solution:
Find Rooms that are not present in the reservation table based and also based on the date criteria.
Room model:
#Entity
#Table(name="room")
public class Room implements java.io.Serializable {
private static final long serialVersionUID = 10L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="roomId", nullable = false)
private long Id;
#Column(name="roomNumber", length = 4, nullable = false) //room number with max length of 4 digits
private String roomNumber;
#Column(name="type", nullable = false, length=10) //queen or king
private String roomType;
#Column(name="properties", nullable = false, length=15) //smoking or non-smoking
private String roomProperties;
#Column(name="price", columnDefinition = "DECIMAL(10,2)", nullable = false) //sets the precision of price to 2 decimal places
private double price;
public Room() {}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public long getId() {
return Id;
}
public void setId(long id) {
this.Id = id;
}
public String getRoomNumber() {
return roomNumber;
}
public void setRoomNumber(String roomNumber) {
this.roomNumber = roomNumber;
}
public String getRoomType() {
return roomType;
}
public void setRoomType(String roomType) {
this.roomType = roomType;
}
public String getRoomProperties() {
return roomProperties;
}
public void setRoomProperties(String roomProperties) {
this.roomProperties = roomProperties;
}
}
Reservation Table:
#Entity
#Table(name="Reservation")
public class Reservation implements Serializable {
private static final Long serialVersionUID = 100L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="reservation_Id", nullable = false)
private long Id;
public long getId() {
return Id;
}
public void setId(long id) {
Id = id;
}
#Column(name="CheckInDate")
private Date checkInDate;
#Column(name="CheckOutDate")
private Date checkOutDate;
#OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name = "guestId", nullable = false)
private Guest guest;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinTable(name = "ReservedRooms", joinColumns = {#JoinColumn(name="resId",
referencedColumnName = "reservation_Id")}, inverseJoinColumns = {#JoinColumn(name="roomId",
referencedColumnName = "roomId")})
private List<Room> roomList;
#Column(name="roomsWanted")
private int roomsWanted;
public int getRoomsWanted() {
return roomsWanted;
}
public void setRoomsWanted(int roomsWanted) {
this.roomsWanted = roomsWanted;
}
public Date getCheckInDate() {
return checkInDate;
}
public void setCheckInDate(Date checkInDate) {
this.checkInDate = checkInDate;
}
public Date getCheckOutDate() {
return checkOutDate;
}
public void setCheckOutDate(Date checkOutDate) {
this.checkOutDate = checkOutDate;
}
public Guest getGuest() {
return guest;
}
public void setGuest(Guest guest) {
this.guest = guest;
}
public List<Room> getRoomList() {
return roomList;
}
public void setRoomList(List<Room> roomList) {
this.roomList = roomList;
}
}
Now method to perform the search availability:
#Override
#Transactional
#SuppressWarnings("unchecked")
public boolean checkAvailability(SearchCriteria searchCriteria) {
String hql = "from Room as r where r.roomType = :roomType1 and r.roomProperties = :roomProperties1 " +
"and r.Id not in (Select res.roomList.Id from Reservation as res left outer join res.roomList " +
"where res.checkInDate <=:checkInDate1 and res.checkOutDate >= :checkOutDate1 " +
" and R.Id = res.roomList.Id) ";
Query query = getSession().createQuery(hql);
query.setParameter("roomType1", searchCriteria.getRoomType());
query.setParameter("roomProperties1", searchCriteria.getRoomProperties());
query.setParameter("checkInDate1", searchCriteria.getCheckInDate());
query.setParameter("checkOutDate1", searchCriteria.getCheckOutDate());
List<Room> roomList = query.list();
if(roomList.isEmpty()) {
return true;
}
return false;
}
But it complains and gives the error:
illegal attempt to dereference collection [reservatio1_.reservation_Id.roomList] with element property reference [Id]
Please what I'm doing wrong as I'm new to hibernate
When you join a collection, you have to name it. You can't use it directly (dereference).
in (Select ROOMS.Id from Reservation as res
left outer join res.roomList AS ROOMS
where res.checkInDate <=:checkInDate1 and res.checkOutDate >= :checkOutDate1
and R.Id = ROOMS.Id)

Composite primary Key and Data truncation error

I'm using Hibernate and MySql and today I setted a composite primary key in one of my table, so below:
DefSelfLearning
And this entity is OneToMany with SelfLearning:
This is my java entity:
#Entity
#Table(name = "defselflearning", catalog = "ats")
public class DefSelfLearning implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#EmbeddedId
private DefSelfLearningKeys defSelfLearningKeys;
private Ecu ecu;
private String excelColumn;
#JsonIgnore
private Set<SelfLearning> selfLearnings = new HashSet<SelfLearning>(0);
public DefSelfLearning() {
}
public DefSelfLearning(DefSelfLearningKeys defSelfLearningKeys, Ecu ecu) {
this.defSelfLearningKeys = defSelfLearningKeys;
this.ecu = ecu;
}
public DefSelfLearning(Ecu ecu, DefSelfLearningKeys defSelfLearningKeys, String excelColumn, Set<SelfLearning> selfLearnings) {
this.ecu = ecu;
this.defSelfLearningKeys = defSelfLearningKeys;
this.excelColumn = excelColumn;
this.selfLearnings = selfLearnings;
}
#Id
public DefSelfLearningKeys getDefSelfLearningKeys() {
return this.defSelfLearningKeys;
}
public void setDefSelfLearningKeys(DefSelfLearningKeys defSelfLearningKeys) {
this.defSelfLearningKeys = defSelfLearningKeys;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "id_ecu", nullable = false)
public Ecu getEcu() {
return this.ecu;
}
public void setEcu(Ecu ecu) {
this.ecu = ecu;
}
#Column(name = "excelColumn", length = 2)
public String getExcelColumn() {
return this.excelColumn;
}
public void setExcelColumn(String excelColumn) {
this.excelColumn = excelColumn;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "defSelfLearning")
public Set<SelfLearning> getSelfLearnings() {
return this.selfLearnings;
}
public void setSelfLearnings(Set<SelfLearning> selfLearnings) {
this.selfLearnings = selfLearnings;
}
}
the class for the composite key:
#Embeddable
public class DefSelfLearningKeys implements Serializable {
private static final long serialVersionUID = 1L;
protected String parName;
protected String description;
protected String note;
public DefSelfLearningKeys() {}
public DefSelfLearningKeys(String parName, String description, String note) {
this.parName = parName;
this.description = description;
this.note = note;
}
#Column(name = "parName", nullable = false, length = 15)
public String getParName() {
return this.parName;
}
public void setParName(String parName) {
this.parName = parName;
}
#Column(name = "description", nullable = false, length = 100)
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
#Column(name = "note", nullable = false, length = 100)
public String getNote() {
return this.note;
}
public void setNote(String note) {
this.note = note;
}
}
and SelfLearning class:
#Entity
#Table(name = "selflearning", catalog = "ats")
public class SelfLearning implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private int idSelfLearning;
private Acquisition acquisition;
private DefSelfLearning defSelfLearning;
private String value;
public SelfLearning() {
}
public SelfLearning(int idSelfLearning, Acquisition acquisition, DefSelfLearning defSelfLearning) {
this.idSelfLearning = idSelfLearning;
this.acquisition = acquisition;
this.defSelfLearning = defSelfLearning;
}
public SelfLearning(int idSelfLearning, Acquisition acquisition, DefSelfLearning defSelfLearning, String value) {
this.idSelfLearning = idSelfLearning;
this.acquisition = acquisition;
this.defSelfLearning = defSelfLearning;
this.value = value;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id_selfLearning", unique = true, nullable = false)
public int getIdSelfLearning() {
return this.idSelfLearning;
}
public void setIdSelfLearning(int idSelfLearning) {
this.idSelfLearning = idSelfLearning;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "id_acquisition", nullable = false)
public Acquisition getAcquisition() {
return this.acquisition;
}
public void setAcquisition(Acquisition acquisition) {
this.acquisition = acquisition;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumns({
#JoinColumn(name = "id_parName", nullable = false),
#JoinColumn(name = "id_description", nullable = false),
#JoinColumn(name = "id_note", nullable = false)
})
public DefSelfLearning getDefSelfLearning() {
return this.defSelfLearning;
}
public void setDefSelfLearning(DefSelfLearning defSelfLearning) {
this.defSelfLearning = defSelfLearning;
}
#Column(name = "value")
public String getValue() {
return this.value;
}
public void setValue(String value) {
this.value = value;
}
}
but when I create a defSelfLearning all work fine, but when I create a SelfLearning I receive MysqlDataTruncation exception:
Caused by: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column 'id_parName' at row 1
This error is enough explined, but I don't find where is the problem, this is the code for SelfLearning creation:
for (DefSelfLearning defSelfLearning:defSelfLearningList){
SelfLearning selfLearning=new SelfLearning();
String key = defSelfLearning.getExcelColumn()+index;
String value = actualRowValues.get(key);
selfLearning.setAcquisition(findByCarAndExcelRow(carServices.findById(acquisitionForm.getCar()), index));
selfLearning.setDefSelfLearning(defSelfLearning);
selfLearning.setValue(value);
System.out.println(selfLearning.getDefSelfLearning().getDefSelfLearningKeys().getParName());
selfLearningServices.create(selfLearning);
}
Do you find where is the problem?Thanks
This is the first row of defSelfLearning and it's where the code fails
if I set manually this it works:
This is a screen of java debug of first code, that fails:
You try to insert a char which is longer than 15 in the column "id_parName"
On your Entities, you have to choose between field and getter. And all the annotations should be on fields, or they should all be on getters, you can't mix both approaches (except if you use the #AccessType annotation).
Hibernate / Jpa will pick up the used approch from the annotation on Id.
Change #Id on the first Embeddable entity to #EmbeddedId and make sure it is on the getter.
SelfLearning wrong mappings the columns, id_parName= id_description, id_description= id_note and id_note=id_parName, but why?
So I read:
When the JoinColumns annotation is used, both the name and the
referencedColumnName elements must be specified in each such
JoinColumn annotation.
I have added this element so:
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumns({
#JoinColumn(name = "id_parName", referencedColumnName="parName", nullable = false),
#JoinColumn(name = "id_description", referencedColumnName="description", nullable = false),
#JoinColumn(name = "id_note", referencedColumnName="note", nullable = false)
})
public DefSelfLearning getDefSelfLearning() {
return this.defSelfLearning;
}
And it works

How to prevent endless loop in hibernate

I have a rest server and client which uses this API. I have a list of hotels and it had passed well until I added bidirectional dependencies to other entities.After that I start receive an endless array of entities which just repeat the same row in database.
It is my first project with hibernate so may be I made trivial mistakes of novice.
Hotel:
#Entity
#Table(name = "hotels", schema = "", catalog = "mydb")
public class HotelsEntity implements HospitalityEntity{
private int idHotel;
private String name;
private String region;
private String description;
// private byte[] photo;
private HotelPropertyEntity property;
private List<RoomEntity> rooms;
#OneToOne(mappedBy = "hotel")
public HotelPropertyEntity getProperty() {
return property;
}
public void setProperty(HotelPropertyEntity property) {
this.property = property;
}
#OneToMany(mappedBy = "hotel")
public List<RoomEntity> getRooms() {
return rooms;
}
public void setRooms(List<RoomEntity> rooms) {
this.rooms = rooms;
}
#Id
#Column(name = "id_hotel", unique = true)
#GeneratedValue(strategy=GenerationType.AUTO)
public int getIdHotel() {
return idHotel;
}
public void setIdHotel(int idHotel) {
this.idHotel = idHotel;
}
#Basic
#Column(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Basic
#Column(name = "region")
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
#Basic
#Column(name = "description")
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
HotelProperty
#Entity
#Table(name = "hotel_property", schema = "", catalog = "mydb")
public class HotelPropertyEntity {
private int idHotelProperty;
private byte hasPool;
private byte hasTennisCourt;
private byte hasWaterslides;
private HotelsEntity hotel;
#Id
#Column(name = "id_hotel_property", unique = true)
#GeneratedValue(strategy=GenerationType.AUTO)
public int getIdHotelProperty() {
return idHotelProperty;
}
public void setIdHotelProperty(int idHotelProperty) {
this.idHotelProperty = idHotelProperty;
}
#Basic
#Column(name = "has_pool", columnDefinition = "BIT", length = 1)
public byte getHasPool() {
return hasPool;
}
public void setHasPool(byte hasPool) {
this.hasPool = hasPool;
}
#Basic
#Column(name = "has_tennis_court", columnDefinition = "BIT", length = 1)
public byte getHasTennisCourt() {
return hasTennisCourt;
}
public void setHasTennisCourt(byte hasTennisCourt) {
this.hasTennisCourt = hasTennisCourt;
}
#Basic
#Column(name = "has_waterslides", columnDefinition = "BIT", length = 1)
public byte getHasWaterslides() {
return hasWaterslides;
}
public void setHasWaterslides(byte hasWaterslides) {
this.hasWaterslides = hasWaterslides;
}
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "id_hotel_property")
public HotelsEntity getHotel() {
return hotel;
}
public void setHotel(HotelsEntity hotel) {
this.hotel = hotel;
}
Room:
#Entity
#Table(name = "room", schema = "", catalog = "mydb")
public class RoomEntity {
private int idRoom;
private String roomType;
private int peopleCapacity;
private Boolean booked;
private Boolean locked;
private HotelsEntity hotel;
private InventoriesEntity inventory;
private RoomPropertyEntity roomProperty;
#OneToOne(mappedBy = "room")
public RoomPropertyEntity getRoom() {
return roomProperty;
}
public void setRoom(RoomPropertyEntity roomProperty) {
this.roomProperty = roomProperty;
}
#OneToOne
#JoinColumn(name = "id_room")
public InventoriesEntity getInventory() {
return inventory;
}
public void setInventory(InventoriesEntity inventory) {
this.inventory = inventory;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "id_hotel")
public HotelsEntity getHotel() {
return hotel;
}
public void setHotel(HotelsEntity hotel) {
this.hotel = hotel;
}
#Id
#Column(name = "id_room")
public int getIdRoom() {
return idRoom;
}
public void setIdRoom(int idRoom) {
this.idRoom = idRoom;
}
#Basic
#Column(name = "room_type")
public String getRoomType() {
return roomType;
}
public void setRoomType(String roomType) {
this.roomType = roomType;
}
#Basic
#Column(name = "people_capacity")
public int getPeopleCapacity() {
return peopleCapacity;
}
public void setPeopleCapacity(int peopleCapacity) {
this.peopleCapacity = peopleCapacity;
}
#Basic
#Column(name = "booked", columnDefinition = "BIT", length = 1)
public Boolean getBooked() {
return booked;
}
public void setBooked(Boolean booked) {
this.booked = booked;
}
#Basic
#Column(name = "locked", columnDefinition = "BIT", length = 1)
public Boolean getLocked() {
return locked;
}
public void setLocked(Boolean locked) {
this.locked = locked;
}
Could you please advise what is a way or ways to tell hibernate to stop this cycle?
p.s
This code contains another one issue. I f I remove one to one dependency and remain only one to many I receive failed to lazily initialize a collection of role: com.example.model.HotelsEntity.rooms, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.example.model.HotelsEntity["rooms"])
You need to mark entity as not serializable for JSON. Please use #JsonIgnore or #JsonIgnoreProperties("field") on one of the sides of the relations (the annotation is class-level).

JPA - Get collection from ManyToOne relationship

I have a table Post and Post_Image
#Entity
#Table(name = "post")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Post.findAll", query = "SELECT p FROM Post p"),
#NamedQuery(name = "Post.findByPostId", query = "SELECT p FROM Post p WHERE p.postId = :postId"),
#NamedQuery(name = "Post.findByTitle", query = "SELECT p FROM Post p WHERE p.title = :title"),
#NamedQuery(name = "Post.findByCreatedDatetime", query = "SELECT p FROM Post p WHERE p.createdDatetime = :createdDatetime")})
public class Post implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#NotNull
#Column(name = "post_id")
private Integer postId;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 500)
#Column(name = "title")
private String title;
#Basic(optional = false)
#NotNull
#Lob
#Size(min = 1, max = 65535)
#Column(name = "content")
private String content;
#Column(name = "created_datetime")
#Temporal(TemporalType.TIMESTAMP)
private Date createdDatetime;
#JoinColumn(name = "user_id", referencedColumnName = "user_id")
#ManyToOne(optional = false)
private User userId;
#JoinColumn(name = "post_type_id", referencedColumnName = "post_type_id")
#ManyToOne(optional = false)
private PostType postTypeId;
public Post() {
Date date = new Date();
this.createdDatetime =new Date(date.getTime());
}
public Post(Integer postId) {
this.postId = postId;
}
public Post(Integer postId, String title, String content) {
this.postId = postId;
this.title = title;
this.content = content;
}
public Integer getPostId() {
return postId;
}
public void setPostId(Integer postId) {
this.postId = postId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getCreatedDatetime() {
return createdDatetime;
}
public void setCreatedDatetime(Date createdDatetime) {
this.createdDatetime = createdDatetime;
}
public User getUserId() {
return userId;
}
public void setUserId(User userId) {
this.userId = userId;
}
public PostType getPostTypeId() {
return postTypeId;
}
public void setPostTypeId(PostType postTypeId) {
this.postTypeId = postTypeId;
}
#Override
public int hashCode() {
int hash = 0;
hash += (postId != null ? postId.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Post)) {
return false;
}
Post other = (Post) object;
if ((this.postId == null && other.postId != null) || (this.postId != null && !this.postId.equals(other.postId))) {
return false;
}
return true;
}
#Override
public String toString() {
return "entity.Post[ postId=" + postId + " ]";
}
}
and
#Entity
#Table(name = "post_image")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "PostImage.findAll", query = "SELECT p FROM PostImage p"),
#NamedQuery(name = "PostImage.findByPostImageId", query = "SELECT p FROM PostImage p WHERE p.postImageId = :postImageId"),
#NamedQuery(name = "PostImage.findByPath", query = "SELECT p FROM PostImage p WHERE p.path = :path"),
#NamedQuery(name = "PostImage.findByTitle", query = "SELECT p FROM PostImage p WHERE p.title = :title")})
public class PostImage implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#NotNull
#Column(name = "post_image_id")
private Integer postImageId;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 500)
#Column(name = "path")
private String path;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 500)
#Column(name = "title")
private String title;
#JoinColumn(name = "post_id", referencedColumnName = "post_id")
#ManyToOne(optional = false)
private Post postId;
public PostImage() {
}
public PostImage(Integer postImageId) {
this.postImageId = postImageId;
}
public PostImage(Integer postImageId, String path, String title) {
this.postImageId = postImageId;
this.path = path;
this.title = title;
}
public Integer getPostImageId() {
return postImageId;
}
public void setPostImageId(Integer postImageId) {
this.postImageId = postImageId;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Post getPostId() {
return postId;
}
public void setPostId(Post postId) {
this.postId = postId;
}
#Override
public int hashCode() {
int hash = 0;
hash += (postImageId != null ? postImageId.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof PostImage)) {
return false;
}
PostImage other = (PostImage) object;
if ((this.postImageId == null && other.postImageId != null) || (this.postImageId != null && !this.postImageId.equals(other.postImageId))) {
return false;
}
return true;
}
#Override
public String toString() {
return "entity.PostImage[ postImageId=" + postImageId + " ]";
}
}
i want to get collection of images for particular post like
Collection objPostImage = objPost.getPostImageCollection()
but manytoone relationship do not provide this functionality to me how can i convert it to one to many or how can i get Image Collection for a post.?
I am new to java so any help and suggestion will be appreciated
thanx in advance...
You can add a java.util.Set of PostImages in your Post object, and use the Hibernate mapping to provide the relationship. This site has a great example of setting up One to Many relationships.
So, for example, you would want to add something like the following to your Post class:
private Set<PostImage> postImages = new HashSet<PostImage>();
#OneToMany(fetch = FetchType.LAZY, mappedBy = "post")
public Set<PostImage> getPostImages() {
return this.postImages;
}
public void setPostImages(Set<PostImage> postImages) {
this.postImages= postImages;
}
Then, in your PostImage class, add a reference to a Post object:
private Post post;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "POST_ID", nullable = false)
public Stock getPost() {
return this.post;
}
public void setPost(Post post) {
this.post= post;
}
After adding that, you will be able to call the getPostImages() method on your Post object.
Try this:
#Entity
#Table(name = "post")
public class Post
{
//....
#OneToMany(mappedBy = "post")
private Set<PostImage> images;
//....
}
#Entity
#Table(name = "post_image")
public class PostImage
{
//....
#JoinColumn(name = "post_id", referencedColumnName = "id")
#ManyToOne(optional = false)
private Post post;
//....
}
The reason why Seth's answer didn't work is because EclipseLink uses fields to access persistence data. (Hibernate uses properties IIRC.) You can specify per class how a JPA provider should access this data.
Using fields:
#Entity
#Access(AccessType.FIELD)
public class SomeEntity
{
#Id
private Long id;
//....
}
Using properties:
#Entity
#Access(AccessType.PROPERTY)
public class SomeEntity
{
private Long id;
//....
#Id
public Long getId()
{
return id;
}
}
However when using #Access(AccessType.PROPERTY) fields are also used (at least in EclipseLink) so something like this is possible:
#Entity
#Access(AccessType.PROPERTY)
public class SomeEntity
{
private Long id;
#Column(name = "text")
private String someText;
//....
#Id
public Long getId()
{
return id;
}
}

persisting a many to many relationship using hibernate and seam

i have a program that communicates with an existing database. There is a composite table that has an employee and a vehicle as its composite key. On the edit or add employee page, their is a dropdown box to select which vehicles the employee prefers and then stores the vehicle list in a hashtable in the employee class. However, the list will not persist, or store, in the composite table. I am new to seam and have spent all day trying to figure this out. Any help would be appreciated.
Here are some of my classes:
Employee:
#Entity
#Table(name = "flower_store_employee", schema = "dbo", catalog = "tyler")
public class FlowerStoreEmployee implements java.io.Serializable, Comparable<FlowerStoreEmployee> {
/**
*
*/
private static final long serialVersionUID = -1727355085366851150L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "employee_id", unique = true, nullable = false)
private Integer employeeId;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "address_id")
private FlowerStoreAddress flowerStoreAddress;
#Column(name = "name_first", length = 25)
#Length(max = 25)
private String nameFirst;
#Column(name = "name_last", length = 25)
#Length(max = 25)
private String nameLast;
#Column(name = "ssn")
private String ssn;
#Column(name = "phone")
private String phone;
#Column(name = "pay")
private int pay;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "flowerStoreEmployee")
private Set<FlowerStoreDelivery> flowerStoreDeliveries = new HashSet<FlowerStoreDelivery>(
0);
#Cascade({org.hibernate.annotations.CascadeType.ALL })
#ManyToMany(fetch = FetchType.LAZY, mappedBy = "flowerStoreEmployees")
//#JoinTable(name = "flower_store_emp_vehicle", schema = "dbo", catalog = "tyler", joinColumns = { #JoinColumn(name = "vehicle_id", nullable = false, updatable = true) }, inverseJoinColumns = { #JoinColumn(name = "employee_id", nullable = false, updatable = true) })
private Set<FlowerStoreVehicle> flowerStoreVehicles = new HashSet<FlowerStoreVehicle>(
0);
public FlowerStoreEmployee() {
}
public FlowerStoreEmployee(int employeeId) {
this.employeeId = employeeId;
}
public FlowerStoreEmployee(FlowerStoreAddress flowerStoreAddress, String nameFirst,
String nameLast, String ssn, String phone, int pay,
Set<FlowerStoreDelivery> flowerStoreDeliveries,
Set<FlowerStoreVehicle> flowerStoreVehicles) {
this.employeeId = employeeId;
this.flowerStoreAddress = flowerStoreAddress;
this.nameFirst = nameFirst;
this.nameLast = nameLast;
this.ssn = ssn;
this.phone = phone;
this.pay = pay;
this.flowerStoreDeliveries = flowerStoreDeliveries;
this.flowerStoreVehicles = flowerStoreVehicles;
}
public int getEmployeeId() {
return this.employeeId;
}
public void setEmployeeId(int employeeId) {
this.employeeId = employeeId;
}
public FlowerStoreAddress getFlowerStoreAddress() {
return this.flowerStoreAddress;
}
public void setFlowerStoreAddress(FlowerStoreAddress flowerStoreAddress) {
this.flowerStoreAddress = flowerStoreAddress;
}
public String getNameFirst() {
return this.nameFirst;
}
public void setNameFirst(String nameFirst) {
this.nameFirst = nameFirst;
}
public String getNameLast() {
return this.nameLast;
}
public void setNameLast(String nameLast) {
this.nameLast = nameLast;
}
public String getSsn() {
return this.ssn;
}
public void setSsn(String ssn) {
this.ssn = ssn;
}
public String getPhone() {
return this.phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public int getPay() {
return this.pay;
}
public void setPay(int pay) {
this.pay = pay;
}
public void setPay(String pay){
this.pay = Integer.parseInt(pay);
}
public Set<FlowerStoreDelivery> getFlowerStoreDeliveries() {
return this.flowerStoreDeliveries;
}
public void setFlowerStoreDeliveries(
Set<FlowerStoreDelivery> flowerStoreDeliveries) {
this.flowerStoreDeliveries = flowerStoreDeliveries;
}
public Set<FlowerStoreVehicle> getFlowerStoreVehicles() {
return this.flowerStoreVehicles;
}
public void setFlowerStoreVehicles(
Set<FlowerStoreVehicle> flowerStoreVehicles) {
this.flowerStoreVehicles = flowerStoreVehicles;
}
public int compareTo(FlowerStoreEmployee emp) {
if(this.employeeId > emp.employeeId){
return 1;
}
else
if(this.employeeId < emp.employeeId){
return -1;
}
else{
return 0;
}
}
Vehicle:
#Entity
#Table(name = "flower_store_vehicle", schema = "dbo", catalog = "tyler")
public class FlowerStoreVehicle implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 5349431404739349258L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "vehicle_id", unique = true, nullable = false)
private int vehicleId;
#Column(name = "vin", length = 17)
#Length(max = 17)
private String vin;
#Column(name = "license", length = 10)
#Length(max = 10)
private String license;
#Column(name = "make", length = 15)
#Length(max = 15)
private String make;
#Column(name = "model", length = 20)
#Length(max = 20)
private String model;
#Column(name = "color", length = 20)
#Length(max = 20)
private String color;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "flowerStoreVehicle")
private Set<FlowerStoreDelivery> flowerStoreDeliveries = new HashSet<FlowerStoreDelivery>(
0);
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "flower_store_emp_vehicle", schema = "dbo", catalog = "tyler", joinColumns = { #JoinColumn(name = "vehicle_id", nullable = false, updatable = false) }, inverseJoinColumns = { #JoinColumn(name = "employee_id", nullable = false, updatable = false) })
private Set<FlowerStoreEmployee> flowerStoreEmployees = new HashSet<FlowerStoreEmployee>(
0);
public FlowerStoreVehicle() {
}
public FlowerStoreVehicle(int vehicleId) {
this.vehicleId = vehicleId;
}
public FlowerStoreVehicle(int vehicleId, String vin, String license,
String make, String model, String color,
Set<FlowerStoreDelivery> flowerStoreDeliveries,
Set<FlowerStoreEmployee> flowerStoreEmployees) {
this.vehicleId = vehicleId;
this.vin = vin;
this.license = license;
this.make = make;
this.model = model;
this.color = color;
this.flowerStoreDeliveries = flowerStoreDeliveries;
this.flowerStoreEmployees = flowerStoreEmployees;
}
public int getVehicleId() {
return this.vehicleId;
}
public void setVehicleId(int vehicleId) {
this.vehicleId = vehicleId;
}
public String getVin() {
return this.vin;
}
public void setVin(String vin) {
this.vin = vin;
}
public String getLicense() {
return this.license;
}
public void setLicense(String license) {
this.license = license;
}
public String getMake() {
return this.make;
}
public void setMake(String make) {
this.make = make;
}
public String getModel() {
return this.model;
}
public void setModel(String model) {
this.model = model;
}
public String getColor() {
return this.color;
}
public void setColor(String color) {
this.color = color;
}
public Set<FlowerStoreDelivery> getFlowerStoreDeliveries() {
return this.flowerStoreDeliveries;
}
public void setFlowerStoreDeliveries(
Set<FlowerStoreDelivery> flowerStoreDeliveries) {
this.flowerStoreDeliveries = flowerStoreDeliveries;
}
public Set<FlowerStoreEmployee> getFlowerStoreEmployees() {
return this.flowerStoreEmployees;
}
public void setFlowerStoreEmployees(
Set<FlowerStoreEmployee> flowerStoreEmployees) {
this.flowerStoreEmployees = flowerStoreEmployees;
}
}
CompositeTableID:
/**
* FlowerStoreEmpVehicleId generated by hbm2java
*/
#Embeddable
public class FlowerStoreEmpVehicleId implements java.io.Serializable {
private int vehicleId;
private int employeeId;
public FlowerStoreEmpVehicleId() {
}
public FlowerStoreEmpVehicleId(int vehicleId, int employeeId) {
this.vehicleId = vehicleId;
this.employeeId = employeeId;
}
#Column(name = "vehicle_id", nullable = false)
public int getVehicleId() {
return this.vehicleId;
}
public void setVehicleId(int vehicleId) {
this.vehicleId = vehicleId;
}
#Column(name = "employee_id", nullable = false)
public int getEmployeeId() {
return this.employeeId;
}
public void setEmployeeId(int employeeId) {
this.employeeId = employeeId;
}
public boolean equals(Object other) {
if ((this == other))
return true;
if ((other == null))
return false;
if (!(other instanceof FlowerStoreEmpVehicleId))
return false;
FlowerStoreEmpVehicleId castOther = (FlowerStoreEmpVehicleId) other;
return (this.getVehicleId() == castOther.getVehicleId())
&& (this.getEmployeeId() == castOther.getEmployeeId());
}
public int hashCode() {
int result = 17;
result = 37 * result + this.getVehicleId();
result = 37 * result + this.getEmployeeId();
return result;
}
}
CompositeTable:
#Entity
#Table(name = "flower_store_emp_vehicle", schema = "dbo", catalog = "tyler")
public class FlowerStoreEmpVehicle implements java.io.Serializable {
private FlowerStoreEmpVehicleId id;
public FlowerStoreEmpVehicle() {
}
public FlowerStoreEmpVehicle(FlowerStoreEmpVehicleId id) {
this.id = id;
}
#EmbeddedId
#AttributeOverrides({
#AttributeOverride(name = "vehicleId", column = #Column(name = "vehicle_id", nullable = false)),
#AttributeOverride(name = "employeeId", column = #Column(name = "employee_id", nullable = false)) })
#NotNull
public FlowerStoreEmpVehicleId getId() {
return this.id;
}
public void setId(FlowerStoreEmpVehicleId id) {
this.id = id;
}
}
and here is the code to save the employee:
public String addEmployee(){
Set<FlowerStoreVehicle> vehicleSet = new HashSet<FlowerStoreVehicle>();
FlowerStoreEmployee n = new FlowerStoreEmployee();
if(first!=null && first!=""){
n.setNameFirst(first);
}
if(last!=null && last!=""){
n.setNameLast(last);
}
if(pay!=null && pay!=""){
int intPay = (int)(Double.parseDouble(pay)*100);
n.setPay(intPay);
}
if(phone!=null && phone!=""){
n.setPhone(phone);
}
if(ssn!=null && ssn!=""){
n.setSsn(ssn);
}
if(vehicle!=null && vehicle!=""){
String[] vehStr = vehicle.split(" ");
for(int i = 0; i < vehStr.length; i++){
int vehId = Integer.parseInt(vehStr[i]);
vehicleSet.add(entityManager.find(FlowerStoreVehicle.class, vehId));
}
}
if(!vehicleSet.isEmpty()){
n.setFlowerStoreVehicles(vehicleSet);
}
entityManager.persist(n);
if(zip!=null && zip!=""){
FlowerStoreZip zipCode = entityManager.find(FlowerStoreZip.class, Integer.parseInt(zip));
if(zipCode==null){
zipCode = new FlowerStoreZip();
if(zip!=null && zip!=""){
zipCode.setZipCode(Integer.parseInt(zip));
}
if(city!=null && city!=""){
zipCode.setCity(city);
}
if(state!=null && city!=""){
zipCode.setState(state);
}
entityManager.persist(zipCode);
}
}
FlowerStoreAddress add = new FlowerStoreAddress();
if(house!=null && house!=""){
add.setHouseNumber(Integer.parseInt(house));
}
if(street!=null && street!=""){
add.setStreet(street);
}
if(zip!=null && zip!=""){
add.setFlowerStoreZip(entityManager.find(FlowerStoreZip.class, Integer.parseInt(zip)));
}
return "/employee.xhtml";
}
If any more info is needed please let me know. Any help will be greatly appreciated. thank you
First of all, check your code, you have a lot of buggy instructions: in Java you compare Strings with the equals() method, not like this: ssn != "".
The root of your problem is not Seam itself but Hibernate. First of all, add elements to the vehicle set via n.getFlowerStoreVehicles().add(...), don't reassign the entire set with n.setFlowerStoreVehicles(...) (this is probably not a problem during entity creation but becomes a problem when modifying the set after the entities are persisted.
The reason for the relationship not being correctly persisted is that FlowerStoreEmployee is the "weak" side of the relationship (the one with the "mappedBy" attribute in the annotation). Move the #JoinTable annotation to the FlowerStoreEmployee class and remove it from FlowerStoreVehicle, remove the mappedBy from FlowerStoreEmployee and put it in the FlowerStoreVehicle (mappedBy="flowerStoreVehicles"). Since the relationship is bi-directional, assign to both sides of the relationship:
FlowerStoreVehicle veh = entityManager.find(FlowerStoreVehicle.class, vehId);
veh.getFlowerStoreEmployees().add(n); // one direction: vehicle -> employee
n.getFlowerStoreVehicles().add(veh); // the other direction: employee -> vehicle
There is no entityManager.persist at the end of your code, apart from persisting the ZipCode no Object is persisted.

Categories

Resources