I'm using Java EE7 with a GlassFish 4.1 Server to build a system where basically you can post Ideas, and each Idea may have tags.
I've declared the entity Idea as:
#Entity
#Table(name = "IDEAS")
public class Idea implements Serializable {
// Id, description, etc.
#ElementCollection
private List<String> tags;
// Getters, Setter, etc.
}
After reading JPA: Query an embeddable List inside an entity I tried to find by Tag the following way:
public List<Idea> getIdeasWithTag(String tag) {
String queryStr = "select ideatags from Idea i "
+ "inner join i.tags ideatags "
+ "where ideatags.tags = :pTag";
Object res = em.createQuery(queryStr)
.setParameter("pTag", tag)
.getResultList();
return (List<Idea>) res;
}
But I'm getting a TransactionRolledbackLocalException caused by:
Caused by: java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager:
Exception Description: Problem compiling [select ideatags from Idea i inner join i.tags ideatags where ideatags.tags = :pTag].
[61, 74] The state field path 'ideatags.tags' cannot be resolved to a valid type.
I appreciate any help, thanks in advance!!
You have some problems with your query:
select ideatags
from Idea i inner join i.tags ideatags
where ideatags.tags = :pTag
You want the result as Idea but you select a List.
You get your List tags in ideatags, therefore you cant get the attribute tag of ideatags.
if you want to search in the list you have to use IN.
You can try this:
select i
from Idea i
where :pTag IN (i.tags)
Try this:
select e from entity e WHERE :element in elements(e.listOfStrings)
elements() - this work!
where :pTag IN (i.tags) is not work (
Related
I am getting an error with the following JPQL query:
#NamedQuery (name = "Customer.getById", query =
"SELECT o
FROM bub.Customer o
WHERE o.user_id = :myid")
[bub.Customer is the #Entity name]
This is an excerpt of the error message I'm receiving:
org.hibernate.HibernateException:
Errors in named queries:
Customer.getById\n
Caused by: org.hibernate.HibernateException:
Errors in named queries: Customer.getById
When I remove the WHERE clause Wildfly allows me to deploy my web app so I know there is something wrong wtih my WHERE clause. Specifically since the column name is user_id in my Customer table I believe there may be an issue with the underscore(_) in the JPQL. I've tried changing the WHERE clause to "WHERE o.userId = :myid" but that didn't work either.
How can I fix the WHERE clause so my website will deploy and still work the correct way?
EDIT:
The relevant method is this:
public static Customer getById (final EntityManager em, final long id)
{
return em.createNamedQuery ("Customer.getById", Customer.class).setParameter ("myid", id).getSingleResult ();
}
I don't think this is the issue though.
EDIT2:
It turns out this was the issue:
#ManyToOne (fetch = FetchType.LAZY)
#JoinColumn (name = "user_id")
private User user;
I ended up changing the JPQL query to this and now it's working:
#NamedQuery (name = "Customer.getById", query =
"SELECT o
FROM bub.Customer o
WHERE o.user = :myid")
In JPQL you don't use the column name, but the attribute name(unless you annotate something else)
I am trying to use the below query with Hibernate's session.createSQLQuery.
The Entity object corresponding to user has an attribute called address.
The address object is created out of 5 fields from table 'user'.
If I do not use an SQLQuery it gets filled auto-magically.
However without the SQLQuery I can't get all the info I would get from the desired joins shown below.
The user entity object also attributes like accessPlan which I am filling up using
.addEntity("accessPlan", AccessPlan.class)
Query:
SELECT
user.*,
ap.*,
country.*,
auth.*,
GROUP_CONCAT(coup.code SEPARATOR ' ') coupons
FROM
user
INNER JOIN access_plan ap ON (user.access_plan = ap.id)
INNER JOIN country ON (user.country=country.code)
LEFT JOIN user_auth auth ON (user.id = auth.userid)
LEFT JOIN (
SELECT
trans.user_id,coupon.code
FROM
payments_transaction AS trans
INNER JOIN payments_coupon coupon ON (trans.payments_coupon_id=coupon.id)
) coup ON (user.id=coup.user_id)
GROUP BY user.id;
What can be the easiest way to fill up the composed address object while using the SQLQuery?
OR
Is there a way to avoid using SQLQuery for a query like this?
Please check below example from the section 'Returning multiple entities'
String sql = "SELECT ID as {c.id}, NAME as {c.name}, " +
"BIRTHDATE as {c.birthDate}, MOTHER_ID as {c.mother}, {mother.*} " +
"FROM CAT_LOG c, CAT_LOG m WHERE {c.mother} = c.ID";
List loggedCats = sess.createSQLQuery(sql)
.addEntity("cat", Cat.class)
.addEntity("mother", Cat.class).list()
In your case, cat = user, mother = address... somewhat like that.
I do not have anything to try out at the moment but I guess this will help.
I am having problems to implement a search in a PostgreSQl table. The table contains columns with empty strng values that causes an error.
Some information from the column design:
Data type: character varying(20)
Default:
Not NULL: No
Primary key: No
My java class annotation for the column:
#Column(name = "codeClient")
private String codeClient;
This query string works when there is no "empty string" value:
SELECT c FROM Client c WHERE c.id = 765432
And my Json returns:
[{"id":765432,"nameClient":"JACK SMITH","codeClient":"234567890"}]
When I change the query to deal with a empty value:
SELECT c.id, c.nameClient, CASE c.codeClient WHEN '' THEN 'nonexistent' else c.codeClient END FROM Client c WHERE c.id = 765432
The query works, but the Json result misses de columns descriptions:
[[765432,"JACK SMITH","234567890"]]
To solve this problem, I change the query to return an object:
SELECT new ClientDTO(c.id, c.nameClient, CASE c.codeClient WHEN '' THEN 'nonexistent' else c.codeCliente END) FROM Client c WHERE c.id = 765432
But Hibernate can't solve when the result is an empty string:
Java.lang.IllegalArgumentException: org.hibernate.QueryException: could not instatiate class [ClientDTO] from tuple
I've tried to use JPA CriteriaBuilder. It works on simple querys, but due to the complexity, I could not implement a query that I need.
I can't change de database design and I need the Json result.
Anybody can help me?
I would put the CASE c.codeClient WHEN '' THEN 'nonexistent' else c.codeCliente END logic in the DTO:
public ClientDTO(){
...
this.codeClient = ("".equals(codeClient)) ? "nonexistent" : c.codeClient;
...
}
and the leave the query as simple as possible:
SELECT new ClientDTO(c.id, c.nameClient, c.codeClient) FROM Client c WHERE c.id = 765432
You can't instantiate ClientDTO probably because that class is not mapped in persistence.xml. You may change 'new ClientDTO()' to 'new Client()'.
i have the following situation:
In the dao class:
...
Query q = em.createNamedQuery("myQuery");
q.setParameter("attr", "value");
List<MyObj> listMyObj = q.getResultList();
...
In my file orm.xlm, i defined this query:
<named-query name="myQuery">
<query><![CDATA[
select m from MyEntity1
where id_est in (select mm.id from MyEntity2 where mm.id_est = :attr)
]]></query>
</named-query>
Everything works, there are no configuration problems and / or code, but this query returns 0 elements, when execute the same query in sql returns items expected . Why? There is something i ignore in JPQL?
In this case, if mm.id_est is a String when you set parameter don't use
" 'value' "
but use
" value "
...this was my problem. Fortunately, thanks to this post I realized that in my code I had written as I wrote here on StackOverflow
I have the following parametrised JPA, or Hibernate, query:
SELECT entity FROM Entity entity WHERE name IN (?)
I want to pass the parameter as an ArrayList<String>, is this possible? Hibernate current tells me, that
java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.lang.String
Is this possible at all?
ANSWER: Collections as parameters only work with named parameters like ":name", not with JDBC style parameters like "?".
Are you using Hibernate's Query object, or JPA? For JPA, it should work fine:
String jpql = "from A where name in (:names)";
Query q = em.createQuery(jpql);
q.setParameter("names", l);
For Hibernate's, you'll need to use the setParameterList:
String hql = "from A where name in (:names)";
Query q = s.createQuery(hql);
q.setParameterList("names", l);
in HQL you can use query parameter and set Collection with setParameterList method.
Query q = session.createQuery("SELECT entity FROM Entity entity WHERE name IN (:names)");
q.setParameterList("names", names);
Leaving out the parenthesis and simply calling 'setParameter' now works with at least Hibernate.
String jpql = "from A where name in :names";
Query q = em.createQuery(jpql);
q.setParameter("names", l);
Using pure JPA with Hibernate 5.0.2.Final as the actual provider the following seems to work with positional parameters as well:
Entity.java:
#Entity
#NamedQueries({
#NamedQuery(name = "byAttributes", query = "select e from Entity e where e.attribute in (?1)") })
public class Entity {
#Column(name = "attribute")
private String attribute;
}
Dao.java:
public class Dao {
public List<Entity> findByAttributes(Set<String> attributes) {
Query query = em.createNamedQuery("byAttributes");
query.setParameter(1, attributes);
List<Entity> entities = query.getResultList();
return entities;
}
}
query.setParameterList("name", new String[] { "Ron", "Som", "Roxi"}); fixed my issue