Bulk update with hibernate - java

Currently we have two endpoints in our API :
One to update one entity
An various ones to update one field of a Collection of entity
The first one only use saveOrUpdate method of hibernate
While the second one create a custom HQL query to update the desired field.
I would like to make only one endpoint. The idea would be receiving a payload representing the entity. Each field of the entity that are not null would be field that we should update.
I wanted to do that in this way, but it doesn't work as setParameter could set parameters that are not in the String.
Any ideas ?
public long update(Collection<Long> toUpdate, SaleItemDTO newValues) {
if (toUpdate.size() == 0) return 0;
StringBuilder hql = new StringBuilder("UPDATE SaleItem SET ");
if (!newValues.getName().isEmpty()) hql.append("name = :name,");
if (newValues.getPrice() != null) hql.append("price = :price,");
if (newValues.getTag() != null) hql.append("tag = :tag,");
if (newValues.getCategory() != null) hql.append("category.id = :categoryId,");
if (newValues.isRecurringSale() != null) hql.append("isRecurringSale = :isRecurringSale,");
if (newValues.isCallProduct() != null) hql.append("callProduct = :callProduct,");
hql.deleteCharAt(hql.length() - 1).append(" WHERE id in :ids");
return this.sessionFactory
.getCurrentSession()
.createQuery(hql.toString())
.setParameter("name", newValues.getName())
.setParameter("price", newValues.getPrice())
.setParameter("tag", newValues.getTag())
.setParameter("categoryId", newValues.getCategory().getId())
.setParameter("isRecurringSale", newValues.isRecurringSale())
.setParameter("callProduct", newValues.isCallProduct())
.setParameter("ids", toUpdate)
.executeUpdate();
}

Okay, fix it with Criteria API
public long update(Collection<Long> toUpdate, SaleItemDTO newValues) {
if (toUpdate.size() == 0) return 0;
CriteriaBuilder criteriaBuilder = this.sessionFactory.getCriteriaBuilder();
// create update
CriteriaUpdate<SaleItem> update = criteriaBuilder.createCriteriaUpdate(SaleItem.class);
// set the root class
Root<SaleItem> saleItemRoot = update.from(SaleItem.class);
// set update and where clause
if (!newValues.getName().isEmpty()) update.set("name", newValues.getName());
if (newValues.getPrice() != null) update.set("price", newValues.getPrice());
//if (newValues.getCategory() != null) update.set("category.id", newValues.getCategory().getId());
if (newValues.getTag() != null) update.set("tag", newValues.getTag());
if (newValues.isRecurringSale() != null) update.set("isRecurringSale", newValues.isRecurringSale());
if (newValues.isCallProduct() != null) update.set("callProduct", newValues.getProduct());
update.where(saleItemRoot.get("id").in(toUpdate));
return this.sessionFactory.getCurrentSession().createQuery(update).executeUpdate();
}

Related

How to get null and filled values from database using hibernate

I am using hibernate to get data from oracle.I have Criterion object to make filter for hibernate select like this
Criterion cr6=null;
if(reqrrn != null)
{
cr6=Restrictions.eq("rrn", reqrrn);//o
}
else{
cr6=Restrictions.like("rrn", "",MatchMode.ANYWHERE);
}
Criterion cr20=null;
if(cardPrefix != null && cardPrefix != "")
{
cr20=Restrictions.eq("prefix", cardPrefix);
}
else{
cr20=Restrictions.like("prefix", "",MatchMode.ANYWHERE);
}
criteria.add(Restrictions.and(cr6, cr20));
i have filters like this, but it is usseless when value is null, for example
cardPrefix value is null in database i want to get all values for cardPrefix ,which are filled and null too, how can i do this ?
i solved it. it will be for all parameters like
if(cardPrefix != null && cardPrefix != "")
{
cr20=Restrictions.eq("prefix", cardPrefix);
}
else{
cr20=Restrictions.like("prefix", "",MatchMode.ANYWHERE);
cr1=Restrictions.isNull("prefix");
cr20=Restrictions.or(cr20, cr1);
}

Spring Hibernate generate dynamic query

I am using hibernate spring where I need to generate query on a condition.
DAO.java
public ReturnData updateUserDetails(Users users, String mailID)
{
if(!users.getImageURL().equals(""))
{
Query query = this.sessionFactory.getCurrentSession().createQuery("UPDATE users SET emailID=:email_ID, name=:name, imageURL=:imageURL WHERE emailID=:emailID")
//setString....
}
else
{
Query query = this.sessionFactory.getCurrentSession().createQuery("UPDATE users SET emailID=:email_ID, name=:name WHERE emailID=:emailID")
//setString....
}
}
In the above code, I check if image also has been uploaded or not. On the basis of this condition, I have to dynamically generate query. I have to rewrite the whole code for query+execution 2 times. Is it the good way, or is there any better way to do this?
You can dynamically append the query conditions to the query string if they are not null. After getting the final list of conditions, you can create Hibernate query.
StringBuilder sqlQuery = new StringBuilder();
Map<String,Object> parameters = new HashMap<String,Object>();
boolean isFirstSearchCriterion = true;
sqlQuery.append("UPDATE users");
if(email_ID!= null && !email_ID.trim().equals("")) {
if(isFirstSearchCriterion) {
sqlQuery.append(" set emailID= :email_ID");
} else {
sqlQuery.append(" and emailID= :email_ID");
}
parameters.put("email_ID",email_ID);
isFirstSearchCriterion = false;
}
if(name!= null && !name.trim().equals("")) {
if(isFirstSearchCriterion) {
sqlQuery.append(" set name= :name");
} else {
sqlQuery.append(" and name= :name");
}
parameters.put("name",name);
isFirstSearchCriterion = false;
}
if(imageURL!= null && !imageURL.trim().equals("")) {
if(isFirstSearchCriterion) {
sqlQuery.append(" set imageURL= :imageURL");
} else {
sqlQuery.append(" and imageURL= :imageURL");
}
parameters.put("imageURL",imageURL);
isFirstSearchCriterion = false;
}
Query query = this.sessionFactory.getCurrentSession().createQuery(sqlQuery);
Set<String> parameterSet = parameters.keySet();
for (Iterator<String> it = parameterSet.iterator(); it.hasNext();) {
String parameter = it.next();
query.setParameter(parameter, parameters.get(parameter));
}
You can simply do without checking empty String, if user has image url it will add in column or else empty url will be pass on.
public ReturnData updateUserDetails(Users users, String mailID)
{
Query query = this.sessionFactory.getCurrentSession().createQuery("UPDATE users SET emailID=:email_ID, name=:name, imageURL=:imageURL WHERE emailID=:emailID")
query.setParameter("imageURL",users.getImageURL(), Hibernate.STRING);
}

How to update a record after extracting

private List<String> getSCFData(int trdCustomerKy, Date lastRunDate, Date currentDate) throws TradeException {
List<String> reportData = null;
String paymentDate = EMPTY_STRING;
String partyId = EMPTY_STRING;
YOWDAO hdDAO = new YOWDAO(mConnection);
List<YOWSCFExtractData> reportItems = hdDAO.getSCFData(trdCustomerKy, lastRunDate, currentDate);
if (null != reportItems && reportItems.size() > 0) {
reportData = new ArrayList<String>();
mTracer.log("Total records retrieved: " + reportItems.size());
for (YOWSCFExtractData data : reportItems) {
String Source = (null != data.getSource()) ? data.getSource() : BLANK_STRING;
String paymentCurrencyCd = (null != data.getPaymentCurrencyCd()) ? data.getPaymentCurrencyCd()
: BLANK_STRING;
String sellerName = (null != data.getSellerName()) ? data.getSellerName() : BLANK_STRING;
String paymentAmount = (null != data.getPaymentAmount()) ? data.getPaymentAmount() : BLANK_STRING;
if (null != data.getPaymentDate()) {
paymentDate = DateUtil.formatDate(data.getPaymentDate());
}
if (null != data.getapplCifId()) {
partyId = hdDAO.getPartyId(mConfiguration.getCustomerKy(), data.getapplCifId());
}
String dataRow = StringUtils.join(new String[] { Source, data.getBankRef(), partyId, sellerName,
data.getPartyId(), paymentAmount, paymentDate, paymentCurrencyCd}, COMMA);
reportData.add(dataRow);
}
}
return reportData;
}
I am extracting the data from oracle database. I want to update the record of a column once it is fetched to a string. for example when I had extracted data.getBanref() then I want to set it some string back in database. how would I do that? I am using hibernate........
What you can do is set the object data whatever values you want and then save it in the hibernate. If you want to update then use session.saveOrUpdate() or if you want to save a new record then use session.save(). Hope that helps!
You can write a hibernate query
Update table_Name column_Name and set it to whatever you want and call this query in your program. It will be easier i think so

Retrieving Cursors from the GAE Datastore

I have a question on how Datastore generate cursors, I have this code below and even if the result list is empty a cursor is still returned:
if(asList){
if(startCursor != null && startCursor.getWebSafeString() != null){
fetchOptions.startCursor(Cursor.fromWebSafeString(startCursor.getWebSafeString()));
res = pq.asQueryResultList(fetchOptions);
} else if(startCursor != null && startCursor.getWebSafeString() == null) {
res = pq.asQueryResultList(fetchOptions);
} else {
res = pq.asList(fetchOptions);
}
} else {
if(startCursor != null && startCursor.getWebSafeString() != null){
fetchOptions.startCursor(Cursor.fromWebSafeString(startCursor.getWebSafeString()));
res = pq.asQueryResultIterable(fetchOptions);
} else if(startCursor != null && startCursor.getWebSafeString() == null){
res = pq.asQueryResultIterable(fetchOptions);
} else {
res = pq.asIterator(fetchOptions);
}
}
return res;
res here is a Query result:
String newCursor = res.getCursor().toWebSafeString();
Even if res list is empty a cursor is returned, it is normal? Or something is wrong with this?
You always get a cursor, because the datastore doesn't know or care if there are any more results. What you should do is check that the cursor actually returns something, and if not don't show the link for more results.
Having these "last position" cursors can be really useful for progressive handling of new data.
As in, if you persist the cursor somewhere, you can poll Datastore for new records every so often - and it's cheap because cursors mean Datastore won't scan rows.

if (specialmarkId != null) {.....} got ignored

I am using auto generated JPAController of Netbeans 8 using Java 1.8.
public void create(Physical physical) {
if (physical.getTalentCollection() == null) {
physical.setTalentCollection(new ArrayList<Talent>());
}
EntityManager em = null;
try {
em = getEntityManager();
em.getTransaction().begin();
Specialmark specialmarkId = physical.getSpecialmarkId();
System.out.println(specialmarkId+ "...nullValue");
if (specialmarkId != null) {
System.out.println(specialmarkId+ "...ain't right");
specialmarkId = em.getReference(specialmarkId.getClass(), specialmarkId.getId());
physical.setSpecialmarkId(specialmarkId);
}
.....
}
During physical object creation, Specialmark (part of physical object) is an optional.
It can have a value or be null.
Specialmark in the table physical allows you to have null values.
When Specialmark is null, the if (specialmarkId != null) {...} should skipped. Instead, it got ignored and proceed.
the error message is
"... An instance of a null PK has been incorrectly provided for this find operation.
at db.jpa.PhysicalJpaController.create(PhysicalJpaController.java:57)"
System.out.println(specialmarkId+ "...nullValue");
output "null...nullValue" it shows specialmarkId value is null
System.out.println(specialmarkId+ "...ain't right");
Output "null...ain't right" shows if (specialmarkId != null) {...} has been ignored even specialmarkId is null.
Why does (specialmarkId != null) {...} not work?
I guess specialmarkId is not really null, but specialmarkId.toString() is overwriten for it to return the string "null".
Instead of
System.out.println(specialmarkId+ "...nullValue");
try something like
System.out.println((specialmarkId != null?
specialmarkId.toString() + "(not null)": "(this IS REALLY NULL)")
+ "...nullValue");

Categories