JPA OR condition with single value - java

I have a table company: companyId number, companyName varchar, address nvarchar.
I want to achieve a goal that user can query to fetch company either using a id or company name, image there is a search box, user only has to input a single value, then it will fetch company information.
I wrote an repository
#Query(value = "select c from CompanyBasicInfo c where c.companyID = ?1 or c.companyName = ?1 ")
List<CompanyBasicInfo> findByCompanyIDOrCompanyName(#PathVariable String input);
But when I query, I got an error: Parameter value [10083769] did not match expected type [java.lang.Long (n/a)]
How can I solve this problem? Most of the materials available are something like
findByFirstnameOrLastname which uses two values. Thanks a lot!

If none of the companies have a name which consists only of digits, you can create 2 methods (by companyId / by company name) and check wether your input is a number.
If you do not want to do this, you can use the "2 params" version :
List<CompanyBasicInfo> findByCompanyIDOrCompanyName(Long companyId, String companyName);
Then parse your input :
List<CompanyBasicInfo> find(String input) {
Long companyId = null;
try {
companyId = Long.valueOf(input);
} catch(Exception ignored){}
return repository.findByCompanyIDOrCompanyName(companyId, input);
}

This is not a problem of parameters amount but of its type
You can try to treat companyId as String in query using cast function like here.
How do I write hql query with cast?
Your code will look like
#Query(value = "select c from CompanyBasicInfo c where cast(c.companyID as String) = ?1 or c.companyName = ?1 ")
List<CompanyBasicInfo> findByCompanyIDOrCompanyName(#PathVariable String input);

Related

JPQL Extract pk of an relation entity without a second query

I have these entities (is an example because i cant share real name entities):
#Entity
public class User { #Id private BigDecimal id; private String name, private Color favouriteColor }
#Entity
public class Color { #Id private Long colorId; private String colorName;}
In the table I have this data:
USER
ID|NAME|FavColor
1 |John| 1
2 |Sarah| 2
3 |Mike| 1
COLOR
1|Red
2|Blue
Now I want make a query that recover all my user data without select Color entity, only its ids.
#Query("new myDto(u.iduser,u.username,u.favcolor) from user u where favcolor in :listcolors")
This makes me an query of the two tables, I want a unique query because i dont need color entities, only the ids.
--
Other option that I am testing is making a implementation of a nativequery like this:
final List<MyDTO> result = new ArrayList<>();
Query q = entityManager.createNativeQuery("SELECT " +
" USER_ID, " +
" USER_NAME, " +
" FAV_COLOR " + +
"FROM USER " +
"WHERE FAV_COLOR IN (?)");
q.setParameter(1, colors.toString().replace("[","").replace("]",""));
Long TRUE = new Long(1L);
final List<Object[]> resultList = q.getResultList();
for (Object[] objects : resultList) {
MyDTOdto = new MyDTO();
dto.userId(((((BigDecimal) objects[0]) != null) ? ((BigDecimal) objects[0]).longValue() : null));
dto.userName(((((String) objects[0]) != null) ? ((String) objects[0]).longValue() : null));
dto.favColor(((((BigDecimal) objects[0]) != null) ? ((BigDecimal) objects[0]).longValue() : null));
result.add(dto);
}
return result;
In this case, I am getting error code (ORA-1722 - Number Not valid). I don't know what I can test now. Some ideas? Thanks
I am guessing you have issues with the SQL generated and your use of the inner join: when you call "u.favcolor" in the select clause, you are telling JPA to perform an inner join from User to Color based on the favcolor relationship. As favcolor is a Color reference, you are going to get the full color row, where as your native query implies you just want the foreign key value. If all you want is the fk/ID value from Color, the query should be:
"SELECT new myDto(u.iduser, u.username, color.id) FROM user u join u.favcolor color WHERE color.id in :listcolors"
This still might perform an inner join from user to color, but it should be in a single statement.
If you want to ensure you avoid the join:
Use EclipseLink's COLUMN JPQL extension to access the foreign key column directly. Something like:
"SELECT new myDto(u.iduser, u.username, COLUMN('FAV_COLOR', u) FROM user u WHERE COLUMN('FAV_COLOR', u) in :listcolors"
Use EclipseLink native query key functionality to access the "FAV_COLOR" foreign key column in the USER table directly for your JPQL queries. This requires a descriptor customizer to access, but allows you to use the foreign key value in JPQL queries directly without having to map it, and without the COLUMN mechanism tying your JPQL queries to a particular database table detail. This would allow a query of the form:
"SELECT new myDto(u.iduser, u.username, u.favColorVal FROM user u join u.favcolor color WHERE u.favColorVal in :listcolors"
Just map the FAV_COLOR as a basic mapping, in addition to the existing favColor reference mapping (or replacing it if you want):
#Basic
#Column(name="FAV_COLOR", updatable=false, insertable=false)
BigDecimal favColorId
This then allows you to use query "SELECT new myDto(u.iduser, u.username, u.favColorId FROM user u join u.favColorId color WHERE u.favColorId in :listcolors" to the same effect, but you can also just return the User instance (marking favColor as lazy and not serializable) as it will have the same data anyway.

Hibernate query to search for a particular sub string in a string field

I have a field in one of my tables that has a field to store urls and the POJO for that table is as follows:
public class ContentDefinition
{
private String contentName;
private int contentId;
private String contentType;
private String contentUrl;
}
I am trying to write a query to check if the contentUrl field contains url that ends with the string address-book.
I am using the following query:
String hql = " from ContentDefinition WHERE contentUrl LIKE '%'address-book'%'";
Query query = getCurrentSession().createQuery(hql);
List<ContentDefinition> resultsList = query.list();
but I am getting an exception:
org.hibernate.hql.ast.QuerySyntaxException: unexpected token: address near line 1, column 130
Is there any solution, my url can be anything, but always ends with /address-book
String hql = " from ContentDefinition WHERE contentUrl LIKE :addressBook ";
Query query = getCurrentSession().createQuery(hql);
query.setParameter("addressBook","address-book");
List<ContentDefinition> resultsList = query.list();
String hql = " from ContentDefinition WHERE contentUrl LIKE '%address-book%' ";
Change above line. Rest of code looks good. I have tested a similar code.
Read upon chapter SQL LIKE Operator.
The doc says:
The LIKE operator is used in a WHERE clause to search for a specified pattern in a column.
where animalType like '%cats%'
Which means, you should change your query from:
String hql = " from ContentDefinition WHERE contentUrl LIKE '%'address-book'%'";
to
String hql = " from ContentDefinition WHERE contentUrl LIKE '%address-book%'";

Not able to fetch resultset in Hibernate using HQL

I'm triggering a query using HQL, normally it should return empty resultset as it doesn't have any records w.r.t it. But, it throws
org.hibernate.exception.SQLGrammarException: could not extract ResultSet
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:106)
My code is
String hql = "FROM com.pck.Person where userId = " + userId;
Query query = session.createQuery(hql);
#SuppressWarnings("unchecked")
List<Dashboard> listUserDetails = query.list(); <-- Problem here.
I'm expecting list size is 0 because there are no records w.r.t userId passed.
What changes do I need to do?
Lets say the value of userId was "abc12"
Given your code, the value of the string called hql would become:
"FROM com.pck.Person where userId = abc12"
If you took the value of that string and tried to run it as a query on any database, most of them would fail to understand that abc12 is a string. Normally it would be interpreted as a variable.
As other users mentioned including the single quotes would produce the desired query, but the recommended way to assign parameter values is this:
String hql = "FROM com.pck.Person where userId = :id"
query.setParameter("id", userId);
Looks like you are missing single quotes around userid.
Try with "FROM com.pck.Person where userId = '" + userId + "'";
or
Use named parameters with query.setParameter("userid", userId);
Posting the full stacktrace would help if this doesn't solve.

Hibernate query for searching part of string

I'm trying to write a hibernate query to search if table Room contains roomname which contains part of string.The string value is in a variable. I wrote a query to get exact room name from the table.
findRoom(String name) {
Query query = em.createQuery("SELECT a FROM Room a WHERE a.roomname=?1");
query.setParameter(1, name);
List rooms = query.getResultList();
return rooms;
}
In sql the query is something like this:
mysql_query("
SELECT *
FROM `table`
WHERE `column` LIKE '%"name"%' or '%"name"' or '"name"%'
");
I want to know the hql query for searching the table that matches my query. I can not use string directly, so the search query has to be veriable based and I need all three types in a query, if it's begin with name, or contains name or ends name.
I would do something like that:
findRoom(String name) {
Query query = em.createQuery("SELECT a FROM Room a"
+ "WHERE a.roomname LIKE CONCAT('%',?1,'%')");
query.setParameter(1, name);
List rooms = query.getResultList();
return rooms;
}
Use like instead of =:
Query query = em.createQuery("SELECT a FROM Room a WHERE a.roomname like ?1");
query.setParameter(1, "%"+name+"%");

Hibernate retrieve results from database based on condition

I am a bit lost when it comes to retrieving results from the database.
My MemberModel consists of 4 fields: id, username, password and email. I have been able to successfully save it to database.
Now I need to retrieve an id of a member who's username equals "Test".
I tried something along the lines:
SQLQuery query = session.createSQLQuery("SELECT id FROM members WHERE username = :username");
query.setString("username", username);
List<MemberModel> returnedMembers = query.list();
MemberModel member = returnedMembers.get(0);
int id = member.getId();
However I get an error that member.getId() cannot be converted to int, since it is MemberModel... But the getter getId() returns int.
I am quite confused. The question is: what would be the easiest and fastes way to retrieve member id based on condition (value of username)?
You are using a native SQL query, but should use HQL query. That means you have to change the query to:
session.createQuery("SELECT m FROM MemberModel m WHERE m.username = :username")
I would change your code into something like this:
public MemberModel getMember(String username) {
Query query = sessionFactory.getCurrentSession().createQuery("from " + MemberModel.class.getName() + " where username = :username ");
query.setParameter("username", username);
return (MemberModel) query.uniqueResult();
}
Then you should be able to do:
MemberModel model = someInstance.getMember("someUsername");
int id = model.getId();
You can also use criteria and restrictions api.
Criteria criteria = session.createCriteria(MemberModel.class);
criteria.add(Restrictions.eq("username", username));
MemberModel member=(MemberModel)criteria.uniqueResult();

Categories