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.
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!!!
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 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
I have this Pojo as my hibernate entity, I am trying to use hibernate to update some rows in my table:
#Entity
public class Money {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id", unique = true, updatable = false, nullable = false)
private Long id;
#Column(name = "userid")
private String userid;
#Column(name = "email")
private String email;
#Column(name = "money")
private double money;
#Column(name = "status")
private String status;
#Column(name = "group_transaction_id")
private String group_transaction_id;
#Column(name = "item_transaction_id")
private String item_transaction_id;
#Column(name = "created_at")
#CreationTimestamp
private Date createdAt;
#Column(name = "updated_at")
private Date updated_at;
public Long getId() {
return id;
}
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid = userid;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public Date getUpdated_at() {
return updated_at;
}
public void setUpdated_at(Date updated_at) {
this.updated_at = updated_at;
}
}
What I am trying to do is:
#Repository
public interface MoneyRepository extends CrudRepository<Winners, Long> {
List<Winners> findAll();
List<Winners> findByUseridAndStatus(String userid, String status);
#Modifying(clearAutomatically = true)
#Transactional
#Query(value = "UPDATE Money w SET w.status = :status WHERE id in :ids")
int testUpdate(#Param("status") String status, #Param("id") List<Long> ids);
}
And in my Controller/Service I am using it like:
#Autowired
PayoutRepository payoutRepository;
public int testUpdateDB() {
List<Long> pendingIds = Arrays.asList(1l, 2l);
int affected = payoutRepository.testUpdate("pending", pendingIds);
return affected;
}
If I don't use #Param("id") List<Long> ids it's complaining about
java.lang.IllegalStateException: For queries with named parameters you
need to use provide names for method parameters. Use #Param for query
method parameters, or when on Java 8+ use the javac flag -parameters.
If I use #Param("id") List<Long> ids it's complaining :
org.hibernate.QueryException: Named parameter [ids] not set
And if change my query to #Query(value = "UPDATE Money w SET w.status = :status WHERE id in :id") without changing anything else (just changed :ids to :id) it works. Can some explain how that mapping works?
#Param("id") tells him the name of the parameter in your query
So it should be #Param("ids") if your query is "UPDATE Money w SET w.status = :status WHERE id in :ids"
If I don't use #Param("id") List<Long> ids it's complaining about
java.lang.IllegalStateException: For queries with named parameters you need to use provide names for method parameters. Use #Param for query method parameters, or when on Java 8+ use the javac flag -parameters.
It's because you need to have a #param for all your paramter to tell him where to map which parameters.
If I use #Param("id") List<Long> ids it's complaining :
org.hibernate.QueryException: Named parameter [ids] not set
It's because now you have a #param annotation so it proceed on and then it does not find any param named id :id in your query #Query
The name in #Param annotation should map the name of the parameter in your query, name after the :
In my client server application, I am using JavaFx as client and Java hibernate as server to db connection.
Problem
I have one save button and for each click on button, envers creates one revision, whether there is no change in table values.
Basically it is not checking old data to new data, just creating revisions.
Here is my bean code
#Entity
#Audited
#Table(name = "DOMAIN")
public class Domain implements java.io.Serializable {
private Long domainId;
private String domainName;
private String dataType;
private Long valueSize;
private Long valuePrecision;
private Long valueScale;
private String valueRangeLow;
private String valueRangeHigh;
private String description;
private String comments;
private Date effectiveStartDate;
private Date effectiveEndDate;
private String status;
public Domain() {
}
public Domain(Long domainId, String domainName, String dataType,
Date effectiveStartDate, Date effectiveEndDate, String status) {
this.domainId = domainId;
this.domainName = domainName;
this.dataType = dataType;
this.effectiveStartDate = effectiveStartDate;
this.effectiveEndDate = effectiveEndDate;
this.status = status;
}
public Domain(Long domainId, String domainName, String dataType,
Long valueSize, Long valuePrecision,
Long valueScale, String valueRangeLow, String valueRangeHigh,
String description, String comments, Date effectiveStartDate,
Date effectiveEndDate, String status) {
this.domainId = domainId;
this.domainName = domainName;
this.dataType = dataType;
this.valueSize = valueSize;
this.valuePrecision = valuePrecision;
this.valueScale = valueScale;
this.valueRangeLow = valueRangeLow;
this.valueRangeHigh = valueRangeHigh;
this.description = description;
this.comments = comments;
this.effectiveStartDate = effectiveStartDate;
this.effectiveEndDate = effectiveEndDate;
this.status = status;
}
#Id
#GeneratedValue(generator = "DOMAIN_SEQ")
#SequenceGenerator(name="DOMAIN_SEQ", sequenceName="DOMAIN_SEQ",allocationSize=1)
#Column(name = "DOMAIN_ID", unique = true, nullable = false, precision = 22, scale = 0)
public Long getDomainId() {
return this.domainId;
}
public void setDomainId(Long domainId) {
this.domainId = domainId;
}
#Column(name = "DOMAIN_NAME", nullable = false, length = 50)
public String getDomainName() {
return this.domainName;
}
public void setDomainName(String domainName) {
this.domainName = domainName;
}
#Column(name = "DATA_TYPE", nullable = false, length = 50)
public String getDataType() {
return this.dataType;
}
public void setDataType(String dataType) {
this.dataType = dataType;
}
#Column(name = "VALUE_SIZE", precision = 22, scale = 0)
public Long getValueSize() {
return this.valueSize;
}
public void setValueSize(Long valueSize) {
this.valueSize = valueSize;
}
#Column(name = "VALUE_PRECISION", precision = 22, scale = 0)
public Long getValuePrecision() {
return this.valuePrecision;
}
public void setValuePrecision(Long valuePrecision) {
this.valuePrecision = valuePrecision;
}
#Column(name = "VALUE_SCALE", precision = 22, scale = 0)
public Long getValueScale() {
return this.valueScale;
}
public void setValueScale(Long valueScale) {
this.valueScale = valueScale;
}
#Column(name = "VALUE_RANGE_LOW", length = 50)
public String getValueRangeLow() {
return this.valueRangeLow;
}
public void setValueRangeLow(String valueRangeLow) {
this.valueRangeLow = valueRangeLow;
}
#Column(name = "VALUE_RANGE_HIGH", length = 50)
public String getValueRangeHigh() {
return this.valueRangeHigh;
}
public void setValueRangeHigh(String valueRangeHigh) {
this.valueRangeHigh = valueRangeHigh;
}
#Column(name = "DESCRIPTION", length = 200)
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
#Column(name = "COMMENTS")
public String getComments() {
return this.comments;
}
public void setComments(String comments) {
this.comments = comments;
}
#Temporal(TemporalType.DATE)
#Column(name = "EFFECTIVE_START_DATE", nullable = false, length = 7)
public Date getEffectiveStartDate() {
return this.effectiveStartDate;
}
public void setEffectiveStartDate(Date effectiveStartDate) {
this.effectiveStartDate = effectiveStartDate;
}
#Temporal(TemporalType.DATE)
#Column(name = "EFFECTIVE_END_DATE", nullable = false, length = 7)
public Date getEffectiveEndDate() {
return this.effectiveEndDate;
}
public void setEffectiveEndDate(Date effectiveEndDate) {
this.effectiveEndDate = effectiveEndDate;
}
#Column(name = "STATUS", nullable = false, length = 50)
public String getStatus() {
return this.status;
}
public void setStatus(String status) {
this.status = status;
}
Problem is only with client server application.
With normal standalone program it is working fine.
Could anyone help me? I stuck at this point. Am i missing any jars or anything else?
If you need more clarification about question then please tell me.
SERVER SIDE CODE
public long saveDomainFromJson(String domainJsonData) throws Exception {
long domainId = 0;
try {
// here I am setting data to bean, getting from client side
Domain domain = getDomainFromJson(domainJsonData);
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
domainId = session.saveOrUpdate(domain);
tx.commit();
HibernateUtil.closeSession();
} catch (Exception e) {
e.printStackTrace();
throw e;
}
return domainId;
}
Json Data
{
"DOMAIN_ID":36,
"DOMAIN_NAME":"Test_Type",
"DOMAIN_DATA_TYPE":"STRING",
"DOMAIN_EFF_START_DATE":"2016-11-08",
"DOMAIN_EFF_END_DATE":"2099-12-31",
"DOMAIN_STATUS":"Draft",
"DOMAIN_DESCRIPTION":"Object Type: Added for testing purpose"
}
Sorry I didn't see this soon, but the problem is your call to session#save. From the javadocs for Session here, you'll notice the following passage:
save() and persist() result in an SQL INSERT, delete() in an SQL DELETE and update() or merge() in an SQL UPDATE. Changes to persistent instances are detected at flush time and also result in an SQL UPDATE. saveOrUpdate() and replicate() result in either an INSERT or an UPDATE.
So you basically want to use session#saveOrUpdate so that you get both insert and update semantics based on the state of your entity.
Since session#save is generating a new INSERT operation, Envers will always create a new revision for that case regardless.