I have a select statement that loads in the class Folders with a one-to-many relationship with File. While this sometimes happens without error, it sometimes gives me a Hibernate error saying that my use of session is unsafe, or that there were two representations of the same collection Folders.file. What am I doing wrong? Thanks for your help!
Folders.java
#Entity
#Table(name= "folders")
public class Folders implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#Column(name = "folder_code")
private Integer folderCode;
#Column(name = "assign_code")
private Integer assignCode;
public Set<File> getFile() {
return file;
}
public void setFile(Set<file> assignments) {
this.file = file;
}
#OneToMany(targetEntity=File.class,cascade=CascadeType.ALL,fetch=FetchType.EAGER)
#JoinColumn(name="assign_code",referencedColumnName="assign_code")
Set<Folder> folder;
public Integer getAssignCode() {
return assignCode;
}
public void setAssignCode(Integer assignCode) {
this.assignCode = assignCode;
}
public Integer getFolderCode() {
return folderCode;
}
public void setFolderCode(Integer folderCode) {
this.folderCode = folderCode;
}
public Date retrieveFileStartDate(){
List<File> file;
if(this.getFile()!=null){
file= new ArrayList<File>(this.getFile());
}else{
file = new ArrayList<File>();
}
return file.size()>0 ? new
Date(file.get(0).getStartDate()): null;
}
}
File.java
#Entity
#Table(name= "file")
public class File implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#Column(name = "assign_code")
private Integer assignCode;
#Column(name = "start_date")
private String startDate;
#Column(name = "end_date")
private String endDate;
public Integer getAssignCode() {
return assignCode;
}
public void setAssignCode(Integer assignCode) {
this.assignCode = assignCode;
}
public String getStartDate() {
return startDate;
}
public void setStartDate(String startDate) {
this.startDate = startDate;
}
public String getEndDate() {
return endDate;
}
public void setEndDate(String endDate) {
this.endDate = endDate;
}
}
I am not sure about the error you are getting but looking at your entities i can say that relationship mapping is not correct.
You are mapping #OneToMany in Folder entity but what about #ManyToOne in File entity?
also define mappedBy attribute to make it work expected.
Folder.java
#OneToMany(targetEntity=File.class,cascade=CascadeType.ALL,fetch=FetchType.EAGER,mappedBy="file")
#JoinColumn(name="assign_code",referencedColumnName="assign_code")
private Set<Folder> folder;
File.java
#ManyToOne
private File file;
//getter and setter
Related
I have a next question: while working with Hibernate 3.3.0 run into a situation when I have two tables with one-to-many relationships and I need to get the list of parents. In each entity must be filled the several fields from the parent table and a list of all children mapped in the parent. For the easiest understanding, I give an example. I have two tables with one-to-many relationships: parent is "recipients" and child is "requisites". And I have two classes whose objects are the rows of these tables. Class for the table of recipients:
#Entity
#Table(name = "recipients")
#JsonFilter(value = "recipientsFilter")
public class POJORecipient implements POJO {
private static final long serialVersionUID = 4436819032452218525L;
#Id
#Column
private long id;
#Version
#Column
private long version;
#Column(name = "client_id")
private long clientId;
#Column
private String inn;
#Column
private String name;
#Column(name = "rcpt_country_code")
private String rcptCountryCode;
#Column(name = "rcpt_passp_ser")
private String rcptPasspSer;
#Column(name = "rcpt_passp_num")
private String rcptPasspNum;
#OneToMany(mappedBy = "recipient", fetch = FetchType.LAZY)
#JsonManagedReference
private Set<POJORequisite> requisites = new HashSet<>();
public POJORecipient(){}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public long getVersion() {
return version;
}
public void setVersion(long version) {
this.version = version;
}
public long getClientId() {
return clientId;
}
public void setClientId(long clientId) {
this.clientId = clientId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getInn() {
return inn;
}
public void setInn(String inn) {
this.inn = inn;
}
public String getRcptCountryCode() {
return rcptCountryCode;
}
public void setRcptCountryCode(String rcptCountryCode) {
this.rcptCountryCode = rcptCountryCode;
}
public String getRcptPasspSer() {
return rcptPasspSer;
}
public void setRcptPasspSer(String rcptPasspSer) {
this.rcptPasspSer = rcptPasspSer;
}
public String getRcptPasspNum() {
return rcptPasspNum;
}
public void setRcptPasspNum(String rcptPasspNum) {
this.rcptPasspNum = rcptPasspNum;
}
public Set<POJORequisite> getRequisites() {
return requisites;
}
public void setRequisites(Set<POJORequisite> requisites) {
this.requisites = requisites;
}
}
and for requisites table:
#Entity
#Table(name = "requisites")
public class POJORequisite implements POJO {
private static final long serialVersionUID = -35864567359179960L;
#Id
#Column
private long id;
#Version
#Column
private long version;
#Column
private String bic;
#Column
private String bill;
#Column
private String comments;
#Column
private String note;
#ManyToOne
#JoinColumn(name = "recipient_id")
#JsonBackReference
private POJORecipient recipient;
public POJORequisite(){}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public long getVersion() {
return version;
}
public void setVersion(long version) {
this.version = version;
}
public String getBic() {
return bic;
}
public void setBic(String bic) {
this.bic = bic;
}
public String getBill() {
return bill;
}
public void setBill(String bill) {
this.bill = bill;
}
public String getComments() {
return comments;
}
public void setComments(String comments) {
this.comments = comments;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public POJORecipient getRecipient() {
return recipient;
}
public void setRecipient(POJORecipient recipient) {
this.recipient = recipient;
}
}
So, I want to select from the recipients only names and all mapped requisites. Consequently, after the selection, I will have a list of POJORecipient objects and in each object filled only the field "name" and set of POJORequisite objects.
As answer of my question I want to discover one of next: how can I do that with help HQL or Criteria API (the second variant is preferable), or understand it is impossible in Hibernate at all, or that this possibility appeared in later versions (also preferably with example). I'm trying to resolve this question for several months now and will be immensely grateful for any help. All clarifications and advices also will be so helpful. Thanks in advance!!!
[Closed]
When calling the findAll() function from the JpaRepository I correctly get a list of the wanted Objects.
When inspecting the list, one can see that all the fields in an Object are set to null.
Checking the Database alle fields are set. Using findAll() on other Entities works perfectly fine.
#Entity
#Table(name = "loc_module")
public class LocModule implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotNull
#Size(max = 255)
#Column(name = "name", length = 255, nullable = false)
private String name;
#NotNull
#Size(max = 255)
#Column(name = "filename", length = 255, nullable = false)
private String filename;
#Size(max = 2048)
#Column(name = "path", length = 2048)
private String path;
#ManyToOne
private LocOutputType outputType;
#ManyToMany(mappedBy = "modules")
#JsonIgnore
private Set<LocKey> keys = new HashSet<>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public LocModule name(String name) {
this.name = name;
return this;
}
public void setName(String name) {
this.name = name;
}
public String getFilename() {
return filename;
}
public LocModule filename(String filename) {
this.filename = filename;
return this;
}
public void setFilename(String filename) {
this.filename = filename;
}
public String getPath() {
return path;
}
public LocModule path(String path) {
this.path = path;
return this;
}
public void setPath(String path) {
this.path = path;
}
public LocOutputType getOutputType() {
return outputType;
}
public LocModule outputType(LocOutputType locOutputType) {
this.outputType = locOutputType;
return this;
}
Any idea what could be causing this?
Thanks in advance!
The problem was finally solved and sadly it was completely out of my control.
Since I was Testing this on a Testing Environment somehow, someone copied the data one the table LocTable in form another table, without my knowledge.
The foreign key set for LocOutputType was therefor referring to a non existing LocOutputType.
Liquibase was then not able to map the rest of the Object.
Weirdly I did not get any sort of error message.
This is very stupid and I should somehow have seen it.
I will mark the question as closed.
I am using postgresql with springboot. So whenever I am using post method to add a new detail in my table instead of autoincrementing id it's going from 1 to 3. It's taking alternate values rather than consecutive values. I have given following properties and then created table:
spring.jpa.hibernate.ddl-auto=create
Didn't create the table manually. What is the reason for this error? This is my entity class.
#Entity
#Table(name = "NORTHBOUND_SUBSCRIPTION")
public class NBSubscription {
#Id
#GeneratedValue
#Column(name = "nb_id")
private Long nbId;
#Column(name = "DEVICE_FILTER")
private String deviceFilter;
#Column(name = "INTERFACE_FILTER")
private String interfaceFilter;
#ManyToOne
#JoinColumn(name="subscriber_id", referencedColumnName="SUBSCRIBER_ID")
private Subscriber subscriber;
#OneToOne
#JoinColumn(name="sensor_group_id", referencedColumnName="ID")
private SensorGroup sensorGroup;
#Column(name = "EVENT_TYPE")
private String eventType;
#Column(name = "SAMPLING_INTERVAL")
private Integer samplingInterval;
#Column(name = "CREATEAT")
#DateTimeFormat(pattern = "dd-MM-yyyy HH:mm")
private Timestamp createAt;
#Column(name = "MODIFIEDAT")
#DateTimeFormat(pattern = "dd-MM-yyyy HH:mm")
private Timestamp modifiedAt;
#Column(name = "CREATEDBY")
private String createdBy;
#Column(name = "MODIFIEDBY")
private String modifiedBy;
#Column(name = "mark_deletion")
private String markDeletion;
public NBSubscription() {
super();
}
public NBSubscription(Subscriber subscriber, SensorGroup sensorGroup) {
super();
this.subscriber = subscriber;
this.sensorGroup = sensorGroup;
}
public Long getNbId() {
return nbId;
}
public void setNbId(Long nbId) {
this.nbId = nbId;
}
public String getDeviceFilter() {
return deviceFilter;
}
public void setDeviceFilter(String deviceFilter) {
this.deviceFilter = deviceFilter;
}
public String getInterfaceFilter() {
return interfaceFilter;
}
public void setInterfaceFilter(String interfaceFilter) {
this.interfaceFilter = interfaceFilter;
}
#JsonIgnore
public Subscriber getSubscriber() {
return subscriber;
}
public void setSubscriber(Subscriber subscriber) {
this.subscriber = subscriber;
}
public SensorGroup getSensorGroup() {
return sensorGroup;
}
public void setSensorGroup(SensorGroup sensorGroup) {
this.sensorGroup = sensorGroup;
}
public Integer getSamplingInterval() {
return samplingInterval;
}
public void setSamplingInterval(Integer samplingInterval) {
this.samplingInterval = samplingInterval;
}
public String getEventType() {
return eventType;
}
public void setEventType(String eventType) {
this.eventType = eventType;
}
public Timestamp getCreateAt() {
return createAt;
}
public void setCreateAt(Timestamp createAt) {
this.createAt = createAt;
}
public Timestamp getModifiedAt() {
return modifiedAt;
}
public void setModifiedAt(Timestamp modifiedAt) {
this.modifiedAt = modifiedAt;
}
public String getMarkDeletion() {
return markDeletion;
}
public void setMarkDeletion(String markDeletion) {
this.markDeletion = markDeletion;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public String getModifiedBy() {
return modifiedBy;
}
public void setModifiedBy(String modifiedBy) {
this.modifiedBy = modifiedBy;
}
Try this
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
if it doesn't work, try using the table sequence
#Id
#GeneratedValue(strategy=SEQUENCE, generator="CUST_SEQ")
Your autoincrement is implemented with a sequence, and by default entities share the same sequence, so the autoincrement values get spread across the entities.
You could assign each entity its own sequence. But be aware sequences don't participate in transactions. That means if you have a rollback there will be a break in the numbering. Occasional gaps are not avoidable.
If you are making this sequence visible to users and they expect the numbering to be contiguous, my advice is to not use a sequence for that, and keep the user-visible counter in a field separate from the id. If it is visible to users, then at some point it will need to change, and you can't change ids.
I am running HQL query to get results from MS SQL Server. The hibernate generated SQL gives the correct output(2 results for eg,) but Hibernate only extracts one result. Even in the stack trace it shows that the query returned one result. I have tried using order by desc and asc but it always gets the one with the lowest ID value. I have looked at my model but there seems to be no fault with it.
I am using createquery("my query").list() method. Did someone encountered the same issue?
createquery("from Analysis a where a.sample = *someNumber* ").list()
The HQL generated SQL gives correct results when I run this on the database
select
analysis0_.idAnalysis as idAnalys1_5_,
analysis0_.changes_timestamp as changes_2_5_,
analysis0_.Analysis_Done_Date as Analysis3_5_,
analysis0_.Analysis_Remarks as Analysis4_5_,
analysis0_.Sample_idSample as Sample_i5_5_,
analysis0_.Analysis_Start_Date as Analysis6_5_,
analysis0_.Analysis_Status as Analysis7_5_
from
Re_at_AIM_User.analysis analysis0_
where
analysis0_.Sample_idSample=*someNumber*
public class Analysis implements Serializable {
private static final long serialVersionUID = -1216945678610624994L;
#Column(name = "changes_timestamp", columnDefinition = "datetime")
#Temporal(TemporalType.TIMESTAMP)
private Date changesTimestamp;
#Column(name = "Analysis_Done_Date", columnDefinition = "datetime")
#Temporal(TemporalType.TIMESTAMP)
private Date doneDate;
#Id
#Column(name = "idAnalysis", columnDefinition = "bigint")
private Integer id;
#Column(name = "Analysis_Remarks")
private String remarks;
#Column(name = "Analysis_Start_Date", columnDefinition = "datetime")
#Temporal(TemporalType.TIMESTAMP)
private Date startDate;
#Column(name = "Analysis_Status")
private String status;
#ManyToOne()
#JoinColumn(name = "Sample_idSample")
private Sample sample;
public Analysis() {
}
public Date getChangesTimestamp() {
return changesTimestamp;
}
public Date getDoneDate() {
return doneDate;
}
public Integer getId() {
return id;
}
public String getRemarks() {
return remarks;
}
public Date getStartDate() {
return startDate;
}
public String getStatus() {
return status;
}
public void setChangesTimestamp(Date changesTimestamp) {
this.changesTimestamp = changesTimestamp;
}
public void setDoneDate(Date doneDate) {
this.doneDate = doneDate;
}
public void setId(Integer idAnalysis) {
this.id = idAnalysis;
}
public void setRemarks(String remarks) {
this.remarks = remarks;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
public void setStatus(String status) {
this.status = status;
}
public Sample getSample() {
return sample;
}
public void setSample(Sample sample) {
this.sample = sample;
}
}
Hibernate method list() is deprecated.
Use getResultList() instead.
It was a terrible mistake. Was using the test database instead. Officially the most stupid first question. Apologies for the bother.
I have two entities that related with One to Many connection. One is Path another is Point, one path can have few points. And I have view on MySQL side that joined those tables using join table. I need to get the result of query to that view. Here is first
#Entity
#Table(name = "paths")
public class Path {
#JsonIgnore
#Id
#Column(name="id")
#GeneratedValue(strategy=GenerationType.AUTO)
private Long pathID;
#Column(name="path_name")
private String pathName;
#Column(name="path_type")
private Long pathType;
#OneToOne(fetch = FetchType.EAGER)
#JoinColumn(name="uid")
#JsonIgnore
private User owner;
#Column(name="path_status")
private Long pathStatus;
#Column(name="description")
private String pathDescription;
#Column(name="created")
private Long created;
#OneToMany(mappedBy = "primaryKey.point", cascade = CascadeType.ALL)
private Set<PathPoints> pathPoints = new HashSet<PathPoints>();
public Long getPathID(){
return this.pathID;
}
public void setPathID(Long pathID){
this.pathID = pathID;
}
public String getPathName(){
return this.pathName;
}
public void setPathName(String pathName){
this.pathName = pathName;
}
public Long getPathType(){
return this.pathType;
}
public void setPathType(Long pathType){
this.pathType = pathType;
}
public Long getPathStatus(){
return this.pathStatus;
}
public void setPathStatus(Long pathStatus){
this.pathStatus = pathStatus;
}
public String getPathDescription(){
return this.pathDescription;
}
public void setPathDescription(String pathDescription){
this.pathDescription = pathDescription;
}
public Long getCreated(){
return this.created;
}
public void setCreated(Long created){
this.created = created;
}
public Set<PathPoints> getPathPoints() {
return pathPoints;
}
public void setPathPoints(Set<PathPoints> pathPoints) {
this.pathPoints = pathPoints;
}
public User getOwner() {
return owner;
}
public void setOwner(User owner) {
this.owner = owner;
}
}
Here is second
#Entity
#Table(name = "path_points")
#AssociationOverrides({
#AssociationOverride(name = "primaryKey.point", joinColumns = #JoinColumn(name = "point_id")),
#AssociationOverride(name = "primaryKey.path", joinColumns = #JoinColumn(name = "path_id"))
})
public class PathPoints{
private PathPointID primaryKey = new PathPointID();
private Long endTime;
private Long startTime;
#Column(name="end_time")
public Long getEndTime() {
return endTime;
}
public void setEndTime(Long endTime) {
this.endTime = endTime;
}
#Column(name="start_time")
public Long getStartTime() {
return startTime;
}
public void setStartTime(Long startTime) {
this.startTime = startTime;
}
#JsonIgnore
#EmbeddedId
public PathPointID getPrimaryKey() {
return primaryKey;
}
public void setPrimaryKey(PathPointID primaryKey) {
this.primaryKey = primaryKey;
}
#Transient
public Point getPoint() {
return primaryKey.getPoint();
}
public void setPoint(Point point) {
this.primaryKey.setPoint(point);;
}
#JsonIgnore
#Transient
public Path getPath() {
return primaryKey.getPath();
}
public void setPath(Path path) {
this.primaryKey.setPath(path);;
}
}
And that is ID class
#Embeddable
public class PathPointID implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Point point;
private Path path;
#ManyToOne(cascade = CascadeType.ALL)
public Point getPoint() {
return point;
}
public void setPoint(Point point) {
this.point = point;
}
#ManyToOne(cascade = CascadeType.ALL)
public Path getPath() {
return path;
}
public void setPath(Path path) {
this.path = path;
}
}
You need to create third entity class and make jpa/hibernate operations with it.
#Entity
#Table(name = "your_view_name")
public class YourView {
#Column(name="someColumnFromYourView")
private String someColumnFromYourView;
#Transient
private List<Point> points;
...
}
and then do
YourView view = ...//get this view data by some parameters
view.setPoints(yourDaoMethodToGetPoints(view));
you can see this example. I'm using PostgreSQL and JPA 2.1 here.I wrote a view on the database and mapped it to JPA entity.There one thing you need to remember - you cannot do write operations on this view.