Hibernate delete by criteria error - java

I have an Entity (persisted on mongodb) called SourceCondition with property workflowID and I want to delete all SourceCondition objects with a particular workflowID.
The entity is:
#Entity
#Table(name="source_conditions")
public class SourceCondition {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#TableGenerator(
name = "source_conditions"
)
private ObjectId id;
public String getId() { return id.toString(); }
public void setId(ObjectId id) { this.id = id; }
#Column(name="workflowID")
private String workflowID;
public SourceCondition() {}
public String getWorkflowID() {
return workflowID;
}
public void setWorkflowID(String workflowID) {
this.workflowID = workflowID;
}
}
The query I execute is:
Session s = HibernateUtil.getSessionFactory().openSession();
Query query = s.createQuery("delete from SourceCondition where workflowID = :wid");
query.setParameter("wid", "sampleID");
int result = query.executeUpdate();
I receive the following error:
Syntax error in query: [delete from com.backend.Models.Source.SourceCondition where workflowID = :wid]
I also tried with:
Query query = s.createQuery("delete SourceCondition where workflowID = :wid");
query.setParameter("wid", "sampleID");
int result = query.executeUpdate();
but I receive the same error.
=====================
EDIT
I bypass the problem with:
Query query1 = s.createQuery("from SourceCondition sc where sc.workflowID = :wid");
query1.setParameter("wid", "sampleID");
List l1 = query1.list();
Iterator<?> it1 = l1.iterator();
while (it1.hasNext())
{
SourceCondition sc = (SourceCondition) it1.next();
s.delete(sc);
s.flush();
}
It is not the best way to achieve deletion, but it works at the moment.

You need to give the SourceCondition a variable name:
delete from SourceCondition sc where sc.workflowID = :wid

Related

update query using #namedquery does not work properly

This is my DUsers class:
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
import java.util.Date;
import java.util.Objects;
#Entity
#Table(name = "d_users")
#NamedQueries({
#NamedQuery(name = "bonsai.dropwizard.dao.d.DUsers.findAll",
query = "select e from DUsers e"),
#NamedQuery(name = "bonsai.dropwizard.dao.d.DUsers.findById",
query = "select e from DUsers e "
+ "where e.oAuthId = :id "),
#NamedQuery(name = "bonsai.dropwizard.dao.d.DUsers.findByOAuthId",
query = "select e from DUsers e "
+ "where e.oAuthId = :oAuthId "),
#NamedQuery(name = "bonsai.dropwizard.dao.d.DUsers.findByEmail",
query = "select e from DUsers e "
+ "where e.email = :email "),
#NamedQuery(name="bonsai.dropwizard.dao.d.DUsers.confirm",
query = "update DUsers set status = 'HELLO' where oAuthId = :id")
})
public class DUsers implements IDdbPojo{
#Id
#GeneratedValue(generator="system-uuid")
#GenericGenerator(name="system-uuid", strategy = "uuid")
private String id;
private String oAuthId;
private String oAuthType;
private String firstName;
private String secondName;
private String city;
private String phone;
private String email;
private String profileLink;
private String profilePic;
private String status;
private String notificationToken;
private boolean confirmed;
private String password;
private String notes;
private java.util.Date created_timestamp;
private java.util.Date updated_timestamp;
.. getters and setters on-going
As you can see, I have defined a few #NamedQueries and they all work properly except the last one that needs to update my database. In order to run this query, I defined two functions:
private void confirmMailDAO(String id) {
namedQuery("bonsai.dropwizard.dao.d.DUsers.confirm").setParameter("id", id);
}
public void confirmMailInternal(String id) {
Session session = sessionFactory.openSession();
try{
ManagedSessionContext.bind(session);
Transaction transaction = session.beginTransaction();
try{
confirmMailDAO(id);
transaction.commit();
}catch (Exception e) {
transaction.rollback();
throw new RuntimeException(e);
}
} finally {
session.close();
ManagedSessionContext.unbind(sessionFactory);
}
}
After this I defined a path followed by a POST request that should update my database but sadly it doesn't.
#POST
#Path("/confirm/{id}")
public void confirmMail(#NotNull #PathParam("id") String id){
DUsers user = AppConfig.getInstance().getdUsersDAO().findByIdInternal(id);
if (user == null) {
throw new NotAuthorizedException("Error");
}
AppConfig.getInstance().getdUsersDAO().confirmMailInternal(id);
}
Does anyone know where am I getting wrong?
You have set param in named query but forgot to execute it.
Pass session to your method and execute like:
private void confirmMailDAO(Session session, String id) {
Query query = session.getNamedQuery("bonsai.dropwizard.dao.d.DUsers.confirm").setParameter("id", id);
query.executeUpdate();
}

Hibernate query to get a different user table data not working

I am trying to simply fetch the records from a table with the following scenario:
User: abc is the one with which I am loggin into my db it has the rights to select.
Table I am trying to access is xyz.customer, DB user xyz has this table customer.
The error that I am getting is that entity not found. even the I have clearly mentioned my class in the package scan. I tried making SqlResultSetMapping and then it said not found again. I put it in another entity class which is working fine and it still said SqlResultSetMapping not found. My code is as follow:
The code where I am calling it and gives error:
List<SampleClass> sampleClass=
entityIBSManager.createNativeQuery("select * from xyz.customer","CustomerMapping").getResultList();
The code of my entity class:
#Entity
#Table(name = "CUSTOMER", catalog = "XYZ")
#NamedQuery(name = "SampleClass.findAll", query = "select p from SampleClass p")
#SqlResultSetMapping(
name = "CustomerMapping",
entities = #EntityResult(
entityClass = SampleClass.class,
fields = {
#FieldResult(name = "customerNo", column = "CUSTOMER_ID"),
#FieldResult(name = "countryCode", column = "COUNTRY_CODE"),
#FieldResult(name = "status", column = "STATUS")}))
public class SampleClass implements Serializable {
#Id
#Column(name="CUSTOMER_ID")
private Long customerNo;
#Id
#Column(name="COUNTRY_CODE")
private String countryCode;
#Column(name="STATUS")
private int status;
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public Long getCustomerNo() {
return customerNo;
}
public void setCustomerNo(Long customerNo) {
this.customerNo = customerNo;
}
public String getCountryCode() {
return countryCode;
}
public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
#Override
public String toString() {
return "PurgeCustomersIBS [customerNo=" + customerNo + ", countryCode=" + countryCode + ", status=" + status + "]";
}
}
In My DB table I have a composite key combination of country code and customer no.
and I have tried using the direct call to my named query and it gives the error of no named query found.
Thankyou for your help in advance.
Here is my stacktrace
07:57:12.006 [readTask_Worker-3] ERROR org.quartz.core.JobRunShell - Job DEFAULT.cSVFileJob threw an unhandled Exception: java.lang.IllegalArgumentException: No query defined for that name [PurgeCustomersIBS.findAll] at org.hibernate.jpa.spi.AbstractEntityManagerImpl.buildQueryFromName(AbstractEntityManagerImpl.java:753) ~[hibernate-entitymanager-5.0.11.Final.jar:5.0.11.Final] at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createNamedQuery(AbstractEntityManagerImpl.java:890) ~[hibernate-entitymanager-5.0.11.Final.jar:5.0.11.Final]

Hibernate: Switched HQL query to SQL query, throws exception: java.lang.ClassCastException

In My DaoImpl class I am trying to fetch list of data of Type TBatchEntry(model class)
#Override
public List<TBatchEntry> getBatchListFormQuery(String batchNo) {
session = sessionFactory.openSession();
List<TBatchEntry> batchListFromQuery = new ArrayList<TBatchEntry>();
try {
tx = session.beginTransaction();
batchListFromQuery = session.createSQLQuery("SELECT * FROM pghms.t_batchentry WHERE t_regNo LIKE '2008%'").list();
tx .commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}
return batchListFromQuery;
}
In my Controller class I am trying to print value but it is throwing error in commented line:
List<TBatchEntry> batchListFromQuery = new ArrayList<TBatchEntry>();
try{
batchListFromQuery = adminService.getBatchListFormQuery(batchNo);
}catch(Exception e){
e.printStackTrace();
}
Iterator its = batchListFromQuery.iterator();
while(its.hasNext()){
batchFromQuery = (TBatchEntry) its.next(); //This line thorws error
System.out.println(batchFromQuery.getName());
}
This is my entity class
#Entity
#Table(name="t_batchEntry")
public class TBatchEntry {
#Id
#Column(name="t_regNo")
private String regNo;
#Column(name="t_name")
private String name;
public String getRegNo() {
return regNo;
}
public void setRegNo(String regNo) {
this.regNo = regNo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
log of tomcat`root cause
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.sv.pghms.model.TBatchEntry
I'd be really thankful, if somebody could help me.
Try this way just change class name and where condition.It is working for me.
Hope so it will work for you.
List<Book> books = this.sf.getCurrentSession().createSQLQuery("select * from Book where book_id > 3")
.addEntity(Book.class)
.list();
for (Book book : books) {
System.out.println("Book Names are :: " + book.getBookName());
}
Why you are catching TBatchEntry into Object class.You can directly catch into TBatchEntry class.
Change Object[] into TBatchEntry Class, because you are selecting all columns from TBatchEntry table right, try below code i think it will work,
1) From Controller,
List batchListFromQuery = new ArrayList<>();
use foreach loop for displaying records
change return type as below :
#Override
public List<TBatchEntry> getBatchListFormQuery(String batchNo) {
session = sessionFactory.openSession();
List<TBatchEntry> batchListFromQuery = new ArrayList<>();
try {
tx = session.beginTransaction();
batchListFromQuery = session.createSQLQuery("SELECT * FROM pghms.t_batchentry WHERE t_regNo LIKE '2008%'").list();
tx .commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}
return batchListFromQuery;
}
After some study I understood the difference between HQL & SQL query in hibernate.
List<TBatchEntry> batchListFromQuery = new ArrayList<TBatchEntry>();
In case of using HQL query:
batchListFromQuery = session.createQuery(sql).list()
In case of using SQL query:
batchListFromQuery = session.createSQLQuery(sql).addEntity(TBatchEntry.class).list();
Difference is:
.addEntity(TBatchEntry.class)

Getting entity from table without having primary key in Hibernate

I'm currently working on a project where I'm trying to get a list of enities from table which does not have a primary key (dk_systemtherapie_merkmale). This table is 1:n related to another table (dk_systemtherapie). See the screenshot for the table structure.
When getting an entry for dk_systemtherapie, the program fetches the Collection "dkSystemtherapieMerkmalesById". However, the first table entry is fetched as often as the number of actual entries in the table is. It never fetches the other entries from dk_systemtherapie_merkmale. I assume it has something to do with the fact that hibernate can't differ between the entries, but I don't know how to fix it.
Table schema
I've created two corresponding entity classes, dk_systemtherapie:
#Entity
#Table(name = "dk_systemtherapie", schema = "***", catalog = "")
public class DkSystemtherapieEntity {
private int id;
private Collection<DkSystemtherapieMerkmaleEntity> dkSystemtherapieMerkmalesById;
#Id
#Column(name = "id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#OneToMany(mappedBy = "dkSystemtherapieByEintragId")
public Collection<DkSystemtherapieMerkmaleEntity> getDkSystemtherapieMerkmalesById() {
return dkSystemtherapieMerkmalesById;
}
public void setDkSystemtherapieMerkmalesById(Collection<DkSystemtherapieMerkmaleEntity> dkSystemtherapieMerkmalesById) {
this.dkSystemtherapieMerkmalesById = dkSystemtherapieMerkmalesById;
}
}
Here the second one, which is accessing the table without a primary key, dk_systhemtherapie_merkmale:
#Entity #IdClass(DkSystemtherapieMerkmaleEntity.class)
#Table(name = "dk_systemtherapie_merkmale", schema = "***", catalog = "")
public class DkSystemtherapieMerkmaleEntity implements Serializable {
#Id private Integer eintragId;
#Id private String feldname;
#Id private String feldwert;
private DkSystemtherapieEntity dkSystemtherapieByEintragId;
#Basic
#Column(name = "eintrag_id")
public Integer getEintragId() {
return eintragId;
}
public void setEintragId(Integer eintragId) {
this.eintragId = eintragId;
}
#Basic
#Column(name = "feldname")
public String getFeldname() {
return feldname;
}
public void setFeldname(String feldname) {
this.feldname = feldname;
}
#Basic
#Column(name = "feldwert")
public String getFeldwert() {
return feldwert;
}
public void setFeldwert(String feldwert) {
this.feldwert = feldwert;
}
#Id
#ManyToOne
#JoinColumn(name = "eintrag_id", referencedColumnName = "id")
public DkSystemtherapieEntity getDkSystemtherapieByEintragId() {
return dkSystemtherapieByEintragId;
}
public void setDkSystemtherapieByEintragId(DkSystemtherapieEntity dkSystemtherapieByEintragId) {
this.dkSystemtherapieByEintragId = dkSystemtherapieByEintragId;
}
}
I assume the problem is releated to the fact that Hibernate is using the following annotation as the one and only id for fetching data from database.
#Id
#ManyToOne
#JoinColumn(name = "eintrag_id", referencedColumnName = "id")
public DkSystemtherapieEntity getDkSystemtherapieByEintragId() {
return dkSystemtherapieByEintragId;
}
This leads to the problem that when getting more than one entry with the same id (as the id is not unique), you will get the number of entries you would like to but hibernate is always fetching the first entry for this id. So in fact you are getting dublicate entries.
So how to fix this?
According to this question: Hibernate and no PK, there are two workarounds which are actually only working when you don't have NULL entries in your table (otherwise the returning object will be NULL as well) and no 1:n relationship. For my understanding, hibernate is not supporting entities on tables without primary key (documentation). To make sure getting the correct results, I would suggest using NativeQuery.
Remove the Annotations and private DkSystemtherapieEntity dkSystemtherapieByEintragId; (incl. beans) from DkSystemtherapieMerkmaleEntity.java und add a constructor.
public class DkSystemtherapieMerkmaleEntity {
private Integer eintragId;
private String feldname;
private String feldwert;
public DkSystemtherapieMerkmaleEntity(Integer eintragId, String feldname, String feldwert) {
this.eintragId = eintragId;
this.feldname = feldname;
this.feldwert = feldwert;
}
public Integer getEintragId() {
return eintragId;
}
public void setEintragId(Integer eintragId) {
this.eintragId = eintragId;
}
public String getFeldname() {
return feldname;
}
public void setFeldname(String feldname) {
this.feldname = feldname;
}
public String getFeldwert() {
return feldwert;
}
public void setFeldwert(String feldwert) {
this.feldwert = feldwert;
}
}
Remove private Collection<DkSystemtherapieMerkmaleEntity> dkSystemtherapieMerkmalesById; (incl. beans) from DkSystemtherapieEntity.java.
Always when you need to get entries for a particular eintrag_id, use the following method instead of the Collection in DkSystemtherapieEntity.java.
public List<DkSystemtherapieMerkmaleEntity> getDkSystemtherapieMerkmaleEntities(int id) {
Transaction tx = session.beginTransaction();
String sql = "SELECT * FROM dk_systemtherapie_merkmale WHERE eintrag_id =:id";
List<Object[]> resultList;
resultList = session.createNativeQuery(sql)
.addScalar("eintrag_id", IntegerType.INSTANCE)
.addScalar("feldname", StringType.INSTANCE)
.addScalar("feldwert", StringType.INSTANCE)
.setParameter("id", id).getResultList();
tx.commit();
List<DkSystemtherapieMerkmaleEntity> merkmale = new ArrayList<>();
for (Object[] o : resultList) {
merkmale.add(new DkSystemtherapieMerkmaleEntity((Integer) o[0], (String) o[1], (String) o[2]));
}
return merkmale;
}
Call getDkSystemtherapieMerkmaleEntities(dkSystemtherapieEntityObject.getid()) instead of getDkSystemtherapieMerkmalesById().

How to add Hibernate HQL/ SQL results (List) to JavaFX TableView (ObservableList) using property?

I'm using hibernate 5.0.7 and JavaFX For UI's.I get a list of data from database,i tried to show them in a tableView,but no thing shown in tableView.
Here is table structure
CREATE TABLE product
(
idproduct serial NOT NULL,
namefr character varying(50),
qtyinhand double precision,
sellprice double precision,
CONSTRAINT product_pkey PRIMARY KEY(idproduct)
)
Object Relational Mapping:
package model;
#Entity
#Table(name = "Product")
#Access(AccessType.PROPERTY)
public class Product {
private LongProperty idProduct;
private StringProperty nameFr;
private DoubleProperty qtyInHand;
private DoubleProperty sellPrice;
public Product() {
idProduct = new SimpleLongProperty();
nameFr = new SimpleStringProperty();
qtyInHand = new SimpleDoubleProperty();
sellPrice = new SimpleDoubleProperty();
}
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "product_seq_gen")
#SequenceGenerator(name = "product_seq_gen", sequenceName = "product_idproduct_seq")
#Column(name = "idproduct", unique = true, nullable = false)
public Long getIdProduct() {
return idProduct.get();
}
public LongProperty idProductProperty() {
return idProduct;
}
public void setIdProduct(Long idProduct) {
this.idProduct.set(idProduct);
}
#Column(name = "nameFr")
public String getNameFr() {
return nameFr.get();
}
public StringProperty nameFrProperty() {
return nameFr;
}
public void setNameFr(String nameFr) {
this.nameFr.set(nameFr);
}
#Column(name = "qtyInHand")
public double getQtyInHand() {
return qtyInHand.get();
}
public DoubleProperty qtyInHandProperty() {
return qtyInHand;
}
public void setQtyInHand(double qtyInHand) {
this.qtyInHand.set(qtyInHand);
}
#Column(name = "sellPrice")
public double getSellPrice() {
return sellPrice.get();
}
public DoubleProperty sellPriceProperty() {
return sellPrice;
}
public void setSellPrice(double sellPrice) {
this.sellPrice.set(sellPrice);
}
}
I'm using hibernate to retrieve the list of products from database:
public ObservableList<Product> findAll() {
try {
session.beginTransaction();
Query query = session.createSQLQuery("select * from product");
ObservableList<Product> list = FXCollections.observableArrayList(query.list());
session.getTransaction().commit();
session.close();
return list;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
After that i set the table view to show data:
tcID.setCellValueFactory(new PropertyValueFactory<Product, Long>("idProduct"));
tcNameFR.setCellValueFactory(new PropertyValueFactory("nameFr"));
tcQtyInHand.setCellValueFactory(new PropertyValueFactory("qtyInHand"));
tcSellPrice.setCellValueFactory(new PropertyValueFactory<Product, Double>("sellPrice"));
ProductDAO dao=new ProductDAO();
tableView.getItems().addAll(dao.findAll());
After that i can't get item showed in tablview, instead of that when i debug
i notice that dao.findAll()returns a list with size>0,but table don't show any thing.
Since you are using a SQL query, Hibernate doesn't know to associate your entity with the query. You can do
SQLQuery query = session.createSQLQuery("select * from product");
query.addEntity(Product.class);
ObservableList<Product> list = FXCollections.observableArrayList(query.list());
It's probably better to use a HQL query though:
// the really concise, but not very readable "from Product" works as the query too
Query query = session.createQuery("select p from Product as p");
ObservableList<Product> list = FXCollections.observableArrayList(query.list());

Categories

Resources