I am new into Spring, though my issue may appear immature.
Here is a big obstacle I have been stuck into. I am trying to choose the right approach to implement search logic based on wildcards, whether to select JDBC, or Hibernate, or JPA and repositories.
I will demonstrate the problem. Let say we have a search form within web page, where someone may put query to retrieve FirstName and LastName, and say for example there are records:
"Fred Fredrickson"
"Albert Jameson"
"Watson Dalbot"
It is possible to use something like *alb*, we should get:
"Albert Jameson"
"Watson Dalbot"
or using ????son we expect to get only "Albert Jameson".
Learning Spring I found that "like" clause may be only hardcoded, something like:
#Query("select u from User u where u.firstname like %?1")
List findByFirstnameEndsWith(String firstname);
in case of using JPA repositories.
I hope my problem has got a bit clearer.
Big thanks in advance for any kind of help or related advice.
I would have use JPA with the following example
#NamedQuery(name="Profile.getPerson", query="SELECT u FROM User u WHERE u.firstName LIKE ?1");
Query query = session.getNamedQuery("Profile.getPerson");
query.setParameter(1, patternYouWant);
query.getResultList();
Related
As the tittle says I want to create some transactions to make queries. In my case I have Wallet and Customer classes and each of them has a type attribute for knowing what type they are. I want, for example to make a query to get all the wallets so I guess I would have to create a query like TYPE=WALLET. The code I use to query is the following.
String queryStr = "{\"selector\": {\"type\": \"wallet\"}}";
QueryResultsIterator<KeyValue> rows = stub.getQueryResult(queryStr);
The things that I don’t know who to structure the string for querying, of if there is a better way of doing this type of queries. Thanks for your help.
I need to optimize a query that iterates over several objects and I wanted Spring Data to let the database handle it. I want to end up with a HashMap<String,String> that looks like
2134_9877, 9877
2134_2344, 2344
3298_9437, 9437
The SQL would be select convert(varchar,b.id)+'_'+convert(varchar,a.id)',a.id from t1 a join t2 b on a.jc = b.jc
So far, I've got Whatever-QL in the repository that looks like:
#Query("SELECT new map (a.bkey, a.akey) FROM mergeTable a WHERE a.discr= ?1")
The problem is, bkey is not unique, it is only unique when paired with akey and the monstrosity that I have to feed it to wants them combined with an underscore: 2345_2177.
I have tried a.bkey.toString and ''+a.bkey and new String(a.bkey) and just string(a.bkey) (that last gives a new exception but still doesn't work) but Spring doesn't like any of these. I can find no questions asking this and it seems I cannot use SQLServer's convert() function as this ain't SQL.
How can I concatenate the Integers as Strings with an underscore in this #Query?
PS: Using the native query that's been debugged in SQLServer throws some weird alias exception in Hibernate so I think 'going native' is predetermined to be a dead end.
If I have understood it right, the 'Whatever-QL' is called JPQL, and the operator CONCAT can be used. Only the use of it, as it accepts two or more parameters depends on the JPA version you are running.
Here is the answer.
JPA concat operator
You could add a getter to your entity like this:
public String getCombinedKey(){
return a.akey + "_" + a.bkey;
}
The advantage is you could handle here null's and other things if you want and it's more reusable in case you need this in another place. If you do it just in the repository you will have to copy it everytime.
Your query would then be:
#Query("SELECT new map (a.combinedKey, a.akey) FROM mergeTable a WHERE a.discr= ?1")
Quick question... so in Hybris, I have a query similar to this:
"SELECT {CPR:pk} FROM {CategoryProductRelation as CPR}, ...."
Basically, I need to extract the Product Code and Category Code from Java which I think are available as source / target respectively but my question is, just like there's ProductModel, CategoryModel, etc. is there anything like that for CategoryProductRelation?, probably something like a generic RelationModel to simply extract source / target and go from there?
You'll need to JOIN in the entities like this
SELECT {CPR:pk}, {c.code} FROM {CategoryProductRelation as CPR
JOIN Category AS c on {CPR.source} = {c.PK} } WHERE ...
Also, you can do that in the Service Layer by simply calling your query and accessing the properties right from the relation type:
..
CategoryProductRelationModel model = result.get(0)
String categoryCode = ((CategoryModel)model.getSource()).getCode()
Depending on your amount of data, this could be pretty ineffecient.
I'm trying to print a list (of only 1 item) but my JPQL statement isn't working due to quotations. I've tried every combination possible it seems but none will work. If anyone has any suggestions or different approaches I'd appreciate it. Note: I found a somewhat similar question on the site before I posted this but the answers aren't working for my case. Thanks
String submittedName=request.getParameter("name");
user=entityManager.find(user.getClass(),submittedName);
Query myQuery=entityManager.createQuery
("SELECT u.password FROM UserData u WHERE u.name=''"+submittedName+"");
List results=myQuery.getResultList();
String convertedResults=results.get(0).toString();
out.println(results);
To summarize what Dennis and Rob are trying to say:
String submittedName=request.getParameter("name");
user=entityManager.find(user.getClass(),submittedName);
Query myQuery=entityManager.createQuery("SELECT u.password FROM UserData u WHERE u.name=:name");
myQuery.setParameter("name", submittedName);
List results=myQuery.getResultList();
String convertedResults=results.get(0).toString();
out.println(results);
I'm new to Liferay development in general, so feel free to point out if I'm going about stuff totally the wrong way.
I'm trying to get a DynamicQuery object of all users within a certain group (I'll use this object to further filter another query I'll do against the message board). The User interface seems to have a roleIds property that I might be able to use, since I already know the roleId I'm interested in. But I can't find the proper way to query if roleIds contains a certain value.
Any ideas on what I want to do?
PS: I would have the exact SQL query I could ask directly, but I'd rather use Liferay's own connection pool, without needing to do some weird ext project thingy.
You don't need a DynamicQuery. These are the methods you are looking for in the classes that Dirk points out:
long[] UserServiceUtil.getRoleUserIds(long roleId)
or
long[] UserLocalServiceUtil.getRoleUserIds(long roleId)
List<User> UserLocalServiceUtil.getRoleUsers(long roleId)
Remember that the methods in the classes XXXLocalServiceUtil are not checking the permissions of the current user.
EDIT: If you are looking for all users with a given role within a given community:
long companyId= _X_; //Perhaps CompanyThreadLocal.getCompanyId() if you don't have it anywhere else?
Role role=RoleLocalServiceUtil.getRole(companyId, "Example Role");
Group group=GroupLocalServiceUtil.getGroup(companyId, "Example Community");
List<UserGroupRole> userGroupRoles = UserGroupRoleLocalServiceUtil.
getUserGroupRolesByGroupAndRole(groupId, role.getRoleId());
for(UserGroupRole userGroupRole:userGroupRoles){
User oneUser=userGroupRole.getUser();
}
The easiest way to access liferays own objects is by using the XXXServiceUtil classes (e.g. RoleServiceUtil.getUserRoles(userId)). Thus you rarely have to deal with any SQL directly. Either the RoleServiceUtil or UserServiceUtil might have what you need.
The roles of an Organizations are stored in the table UserGroupRole, so if you want to get the owner of an Organization you must use the following code:
boolean isOrgOwner =
UserGroupRoleLocalServiceUtil.hasUserGroupRole(
usr.getUserId(),
this.currentOrganization.getGroupId(),
RoleConstants.ORGANIZATION_OWNER);
If you want to retrieve all the Organization Owners of an organization:
List<User> administrators = new LinkedList<>();
List<UserGroupRole> allOrganizationAdministrators =
UserGroupRoleLocalServiceUtil.getUserGroupRolesByGroupAndRole(
this.currentOrganization.getGroupId(), roleId);
for (UserGroupRole userGroupRoleTemp : allOrganizationAdministrators) {
administrators.add(userGroupRoleTemp.getUser());
}
Cheers!