SQLGrammarException: No value specified for parameter 1 with criteria - java

1-1 association:
#OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "messageDetails")
public MessageEntry getMessageEntry() {
return messageEntry;
}
#OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
public MessageDetails getMessageDetails() {
return messageDetails;
}
Want to load dependent entry in stateless session:
MessageDetails messageDetails =
(MessageDetails) sess.createCriteria(MessageDetails.class)
.add(Restrictions.eq("messageEntry", messageEntry))
.uniqueResult();
I get
Exception in thread "main" org.hibernate.exception.SQLGrammarException: No value specified for parameter 1
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:122)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
The SQL is not what I want. May be I don't understand something?
03:21:13,274 DEBUG SQL:104 - /* criteria query */ select this_.id as id11_0_, this_.date as date11_0_, this_.messageId as messageId11_0_, this_.replyTo as replyTo11_0_, this_.subject as subject11_0_ from MessageDetails this_ where this_.id=?
I want to select MessageDetails by its property messageEntry, isn't that possible? Thanx.

Related

delete children without update them before #OneToMany

I have a problem with hybernate
I have 2 classes like that :
public Class Race {
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="race", orphanRemoval = true)
private List<Lap> laps = new ArrayList<>(0);
...
}
public Class Lap {
#ManyToOne(fetch = FetchType.LAZY, cascade=CascadeType.REFRESH)
#JoinColumn(name = "RACE_ID", nullable = false)
private Race race;
#OneToOne(mappedBy = "nextLap", fetch = FetchType.LAZY)
private Lap previousLap;
#OneToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
#JoinColumn(name = "NEXT_ID")
private Lap nextLap;
...
}
In my database I also have a unique constraint with NEXT_ID and RACE_ID
My problem is when I want to delete my Race, with
txn = session.getTransaction();
txn.begin();
race = session.merge(race);
session.remove(race);
session.flush(); //=>Exception here
txn.commit();
I get the result:
javax.persistence.PersistenceException:
org.hibernate.exception.ConstraintViolationException: could not
execute batch at
org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)
at
org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
at
org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1364)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1347)
at
package.DAORace.deleteRace(DAORace.java:122)
Caused by: java.sql.BatchUpdateException: ORA-00001: unique constraint
(LAP_UK1) violated
Hibernate do an update on my lap when I delete the race and my contraint is violated.
My question is how to delete children properly, without update, when I delete parent ?
Note : If I have only one child, I can delete it without any exception, if I have 2 or more children, I have an exception.
Thank you for your help !
For removing entities as a cascade, the best approach is removing them with a few queries.
For example:
em.createQuery("delete from Lap p where p.race.id = :id).setParameter("id", id).executeUpdate();
em.createQuery("delete from Race r where r.id = :id).setParameter("id", id).executeUpdate();
https://thorben-janssen.com/avoid-cascadetype-delete-many-assocations/ read here for better understanding.

#Where clause does not work inside hibernate join query

I have 2 entities with #Where annotation. First one is Category;
#Where(clause = "DELETED = '0'")
public class Category extends AbstractEntity
and it has the following relation;
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "category")
private Set<SubCategory> subCategories = Sets.newHashSet();
and second entity is SubCategory;
#Where(clause = "DELETED = '0'")
public class SubCategory extends AbstractEntity
and contains corresponding relation;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "CATEGORY_ID")
private Category category;
Whenever I call the following Dao method;
#Query(value = "select distinct category from Category category join fetch category.subCategories subcategories")
public List<Category> findAllCategories();
I got the following sql query;
select
distinct category0_.id as id1_3_0_,
subcategor1_.id as id1_16_1_,
category0_.create_time as create2_3_0_,
category0_.create_user as create3_3_0_,
category0_.create_userip as create4_3_0_,
category0_.deleted as deleted5_3_0_,
category0_.update_time as update6_3_0_,
category0_.update_user as update7_3_0_,
category0_.update_userip as update8_3_0_,
category0_.version as version9_3_0_,
category0_.name as name10_3_0_,
subcategor1_.create_time as create2_16_1_,
subcategor1_.create_user as create3_16_1_,
subcategor1_.create_userip as create4_16_1_,
subcategor1_.deleted as deleted5_16_1_,
subcategor1_.update_time as update6_16_1_,
subcategor1_.update_user as update7_16_1_,
subcategor1_.update_userip as update8_16_1_,
subcategor1_.version as version9_16_1_,
subcategor1_.category_id as categor11_16_1_,
subcategor1_.name as name10_16_1_,
subcategor1_.category_id as categor11_3_0__,
subcategor1_.id as id1_16_0__
from
PUBLIC.t_category category0_
inner join
PUBLIC.t_sub_category subcategor1_
on category0_.id=subcategor1_.category_id
where
(
category0_.DELETED = '0'
)
Could you please tell me why the above query lacks
and subcategor1_.DELETED = '0'
inside its where block?
I have just solved a similar problem in my project.
It is possible to put #Where annotation not only on Entity, but on also on your child collection.
According to the javadoc:
Where clause to add to the element Entity or target entity of a collection
In your case, it would be like :
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "category")
#Where(clause = "DELETED = '0'")
private Set<SubCategory> subCategories = Sets.newHashSet();
Please find a similar issues resolved here
I believe thus solution is not as invasive compared to using Hibernate Filters.These filters are disabled by default and operate on Session level, thus enabling them each time new Session opens is extra work especially when your DAO works through abstractions like Spring Data
This is a quick reply;
#Where(clause = "DELETED = '0'")
public class SubCategory extends AbstractEntity
Where will effect when direct query for SubCategry.
To not get deleted sub categories use Hibernate Filters
as exampled on here

Hibernate, Criteria, Projection, Transformer.aliasToBean and List<T> issue

I want select an entity with some determined fields. Other fields let be NULL.
My issue...
EntA has refences to EntB and list of EntC.
class EntA {
#Id
#GenericGenerator(name = "unique_id", strategy = "uuid")
#GeneratedValue(generator = "unique_id")
#Column(name = "id", nullable = false, length = 32, unique = true)
private String id;
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "entbs", nullable = false, unique = false)
private EntB entB;
#OneToMany(mappedBy = "entcs", fetch = FetchType.LAZY)
#OnDelete(action = OnDeleteAction.CASCADE)
#JsonIgnore
private List<EntC> listEntC;
... other fields , getters & setters ...
}
A few days ago i had complemented bacis procedure of selection with folowing code. Code provides selection an object with some determined fields, other fields will be as null. Some like as SQL`s "select fieldA, fieldJ from table ..."
public List<EntA> select(..., List<String> fieldList, ...) {
Criteria crit = sessionFactory.getCurrentSession().createCriteria(EntA.class);
...
ProjectionList pl = Projections.projectionList();
for (String prop : fieldList) {
pl.add(Projections.property(prop), prop);
}
crit.setProjection(pl);
crit.setResultTransformer(Transformers.aliasToBean(EntA.class));
...
return crit.list();
}
All works good, for example: i select some fields (not all in entity) even repeat some field. Result = object of class EntA which has fields "id","EntB" and "other_field_name" with values, other fields are NULL.
List<String> fieldList = new ArrayList<String>();
fieldList.add("id");
fieldList.add("entB");
fieldList.add("entB");
fieldList.add("entB");
fieldList.add("other_field_name");
select(..., fieldList, ...);
Hibernate:
/* criteria query */ select
this_.id as y0_,
this_.entB as y1_,
this_.entB as y2_,
this_.entB as y3_,
this_.other_field_name as y4_
from
EntA this_
Hibernate:
select
entb0_.id as id1_12_0_,
entb0_.idx as idx2_12_0_,
entb0_.name as name3_12_0_
from
EntB entb0_
where
entb0_.id=?
But...
fieldList.add("id");
fieldList.add("listEntC");
select(..., fieldList, ...);
Hibernate:
/* criteria query */ select
this_.id as y0_,
this_.id as y1_
from
EntA this_
java.lang.ArrayIndexOutOfBoundsException: 1
at org.hibernate.loader.criteria.CriteriaLoader.getResultRow(CriteriaLoader.java:168)
at org.hibernate.loader.criteria.CriteriaLoader.getResultColumnOrRow(CriteriaLoader.java:148)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:753)
at org.hibernate.loader.Loader.processResultSet(Loader.java:952)
at org.hibernate.loader.Loader.doQuery(Loader.java:920)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:354)
at org.hibernate.loader.Loader.doList(Loader.java:2553)
at org.hibernate.loader.Loader.doList(Loader.java:2539)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2369)
at org.hibernate.loader.Loader.list(Loader.java:2364)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:126)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1682)
at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:380)
*************************************.select(BaseDao.java:141)
Several days i debug my code & hibernate-core sources and cant understand:
if i use simple selection without projections and transformers, i get normal object of EntA which List<EntC> lstEntC has values
if i use projection without transformers - i get not EntA
if i use projection with transformers, a can select only non-list fields
Have you any ideas about how to use Criteria`s selection with projection result into class?
thanks.

Hibernate join cannot cast exception many to many

I got a question regarding hibernate.
I have to classes with many to many relationship and try to make a select. The problem is I am getting an exception. Can you help?
#Entity(name = "pracownik")
#Inheritance(strategy = InheritanceType.JOINED)
#Proxy(lazy = false)
public class Pracownik extends Osoba {
#ManyToMany(fetch = FetchType.EAGER, cascade = { CascadeType.ALL })
#JoinTable(name = "grafikpracownika", joinColumns = { #JoinColumn(name = "idosoby") },
inverseJoinColumns = { #JoinColumn(name = "idgrafiku") })
private List<Grafik> grafiki = new ArrayList<>();
}
The second entity
#Entity (name = "grafik")
#Proxy(lazy = false)
public class Grafik {
#ManyToMany (mappedBy = "grafiki",cascade = { CascadeType.ALL })
private List <Pracownik> pracownik = new ArrayList<>();
}
The method I developed is:
public List<Pracownik> getWszyscyPracownicyGrafiku() {
List<Pracownik> pracownicy = new ArrayList<>();
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction transaction = session.beginTransaction();
Query query = session.createQuery("from pracownik as p join p.grafiki");
pracownicy = query.list();
transaction.commit();
return pracownicy;
}
And the exception is:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to model.Pracownik
Any idea what is wrong?
I also would like to add a "where" but it should be easy after I get rid of this exception.
I also tried with "normal" sql
SELECT * from pracownik p join grafikpracownika g on p.idosoby = g.idosoby where idgrafiku = 6
but what I am getting is:
org.hibernate.loader.custom.NonUniqueDiscoveredSqlAliasException: Encountered a duplicated sql alias [idosoby] during auto-discovery of a native-sql query
You're selecting from two tables without explicit select clause, therefore Hibernate produces a list of tuples (Pracownik, Grafik) as a result.
If you want only Pracowniks (i.e. join is needed to create condition on p.grafiki in where), use
select distinct p from pracownik as p join p.grafiki
If join is used to instruct Hibernate to fetch associated Grafiks, use join fetch:
from pracownik as p join fetch p.grafiki

JPA2:i use a JoinColumn as queryparam to create a query and a exception occurred ,why

#JoinColumn(name = "want_uid", referencedColumnName = "id")
#ManyToOne
private BookUsers wantUid;
#JoinColumn(name = "sale_uid", referencedColumnName = "id")
#ManyToOne
private BookUsers saleUid;
#JoinColumn(name = "book_id", referencedColumnName = "id")
this code is from a entity bean
and i write a query using want_uid as queryparam .as fllows:
BookUsers bookUsers=userDA.findUserByID(wantID);
Query query= em.createQuery("SELECT b FROM BookOrder b WHERE b.want_uid = :want_uid");
query.setParameter("want_uid", bookUsers);
a exception occurred:
javax.servlet.ServletException: java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager:
Exception Description: Error compiling the query [SELECT b FROM BookOrder b WHERE b.want_uid = :want_uid], line 1, column 34: unknown state or association field [want_uid] of class [com.xbook.entities.BookOrder].
i failed to find the reason...
can you tell me ?
Thanks
In the query
b.want_uid
needs to be changed to
b.wantUid
So,
SELECT b FROM BookOrder b WHERE b.wantUid = :want_uid

Categories