I want to dynamic search with Criteria API in Java.
In the code I wrote, we need to write each entity in the url bar in JSON. I don't want to write "plaka".
The URL : <localhost:8080/api/city/query?city=Ankara&plaka=> I want to only "city" or "plaka"
Here we need to write each entity, even if we are going to search with only 1 entity. Type Entity and it should be empty.
My code is as below. Suppose there is more than one entity, what I want to do is to search using a single entity it wants to search. As you can see in the photo, I don't want to write an entity that I don't need. can you help me what should I do?
My code in Repository
public interface CityRepository extends JpaRepository<City, Integer> , JpaSpecificationExecutor<City> {
}
My code in Service
#Service
public class CityServiceImp implements CityService{
private static final String CITY = "city";
private static final String PLAKA = "plaka";
#Override
public List<City> findCityByNameAndPlaka(String cityName, int plaka) {
GenericSpecification genericSpecification = new GenericSpecification<City>();
if (!cityName.equals("_"))
genericSpecification.add(new SearchCriteria(CITY,cityName, SearchOperation.EQUAL));
if (plaka != -1)
genericSpecification.add(new SearchCriteria(PLAKA,plaka, SearchOperation.EQUAL));
return cityDao.findAll(genericSpecification);
}
#Autowired
CityRepository cityDao;
My code in Controller
#RestController
#RequestMapping("api/city")
public class CityController {
#Autowired
private final CityService cityService;
public CityController(CityService cityService) {
this.cityService = cityService;
#GetMapping("/query")
public List<City> query(#RequestParam String city, #RequestParam String plaka){
String c = city;
int p;
if (city.length() == 0)
c = "_";
if (plaka.length() == 0) {
p = -1;
}
else
p = Integer.parseInt(plaka);
return cityService.findCityByNameAndPlaka(c,p);
}
My code in SearchCriteria
public class SearchCriteria {
private String key;
private Object value;
private SearchOperation operation;
public SearchCriteria(String key, Object value, SearchOperation operation) {
this.key = key;
this.value = value;
this.operation = operation;
}
public String getKey() {
return key;
}
public Object getValue() {
return value;
}
public SearchOperation getOperation() {
return operation;
}
My code in GenericSpecification
public class GenericSpecification<T> implements Specification<T> {
private List<SearchCriteria> list;
public GenericSpecification() {
this.list = new ArrayList<>();
}
public void add(SearchCriteria criteria){
list.add(criteria);
}
#Override
public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
List<Predicate> predicates = new ArrayList<>();
for (SearchCriteria criteria : list) {
if (criteria.getOperation().equals(SearchOperation.GREATER_THAN)) {
predicates.add(builder.greaterThan(
root.get(criteria.getKey()), criteria.getValue().toString()));
} else if (criteria.getOperation().equals(SearchOperation.LESS_THAN)) {
predicates.add(builder.lessThan(
root.get(criteria.getKey()), criteria.getValue().toString()));
} else if (criteria.getOperation().equals(SearchOperation.GREATER_THAN_EQUAL)) {
predicates.add(builder.greaterThanOrEqualTo(
root.get(criteria.getKey()), criteria.getValue().toString()));
} else if (criteria.getOperation().equals(SearchOperation.LESS_THAN_EQUAL)) {
predicates.add(builder.lessThanOrEqualTo(
root.get(criteria.getKey()), criteria.getValue().toString()));
} else if (criteria.getOperation().equals(SearchOperation.NOT_EQUAL)) {
predicates.add(builder.notEqual(
root.get(criteria.getKey()), criteria.getValue()));
} else if (criteria.getOperation().equals(SearchOperation.EQUAL)) {
predicates.add(builder.equal(
root.get(criteria.getKey()), criteria.getValue()));
} else if (criteria.getOperation().equals(SearchOperation.MATCH)) {
predicates.add(builder.like(
builder.lower(root.get(criteria.getKey())),
"%" + criteria.getValue().toString().toLowerCase() + "%"));
} else if (criteria.getOperation().equals(SearchOperation.MATCH_END)) {
predicates.add(builder.like(
builder.lower(root.get(criteria.getKey())),
criteria.getValue().toString().toLowerCase() + "%"));
}
}
return builder.and(predicates.toArray(new Predicate[0]));
}
My code in SearchOperation
public enum SearchOperation {
GREATER_THAN,
LESS_THAN,
GREATER_THAN_EQUAL,
LESS_THAN_EQUAL,
NOT_EQUAL,
EQUAL,
MATCH,
MATCH_END,
}
The good thing about the Criteria API is that you can use the CriteriaBuilder to build complex SQL statements based on the fields that you have. You can combine multiple criteria fields using and and or statements with ease.
How I approached something similar int he past is using a GenericDao class that takes a Filter that has builders for the most common operations (equals, qualsIgnoreCase, lessThan, greaterThan and so on). I actually have something similar in an open-source project I started: https://gitlab.com/pazvanti/logaritmical/-/blob/master/app/data/dao/GenericDao.java
https://gitlab.com/pazvanti/logaritmical/-/blob/master/app/data/filter/JPAFilter.java
Next, the implicit DAO class extends this GenericDao and when I want to do an operation (ex: find a user with the provided username) and there I create a Filter.
Now, the magic is in the filter. This is the one that creates the Predicate.
In your request, you will receive something like this: field1=something&field2=somethingElse and so on. The value can be preceded by the '<' or '>' if you want smaller or greater and you initialize your filter with the values. If you can retrieve the parameters as a Map<String, String>, even better.
Now, for each field in the request, you create a predicate using the helper methods from the JPAFilter class and return he resulted Predicate. In the example below I assume that you don't have it as a Map, but as individual fields (it is easy to adapt the code for a Map):
public class SearchFilter extends JPAFilter {
private Optional<String> field1 = Optional.empty();
private Optional<String> field2 = Optional.empty();
#Override
public Predicate getPredicate(CriteriaBuilder criteriaBuilder, Root root) {
Predicate predicateField1 = field1.map(f -> equals(criteriaBuilder, root, "field1", f)).orElse(null);
Predicate predicateField2 = field2.map(f -> equals(criteriaBuilder, root, "field2", f)).orElse(null);
return andPredicateBuilder(criteriaBuilder, predicateField1, predicateField2);
}
}
Now, I have the fields as Optional since in this case I assumed that you have them as Optional in your request mapping (Spring has this) and I know it is a bit controversial to have Optional as input params, but in this case I think it is acceptable (more on this here: https://petrepopescu.tech/2021/10/an-argument-for-using-optional-as-input-parameters/)
The way the andPredicateBuilder() is made is that it works properly even if one of the supplied predicates is null. Also, I made s simple mapping function, adjust to include for < and >.
Now, in your DAO class, just supply the appropriate filter:
public class SearchDao extends GenericDAO {
public List<MyEntity> search(Filter filter) {
return get(filter);
}
}
Some adjustments need to be made (this is just starter code), like an easier way to initialize the filter (and doing this inside the DAO) and making sure that that the filter can only by applied for the specified entity (probably using generics, JPAFIlter<T> and having SearchFilter extends JPAFilter<MyEntity>). Also, some error handling can be added.
One disadvantage is that the fields have to match the variable names in your entity class.
I have a single table called Tags that stores a "Tag" as a row, regardless of what specific subclass they represent. Some rows represent modbus tags, some snmp, some other protocols. All classes inheriting from Tag store their data in this one table, and unused columns simply contain null values.
At the moment, I have DAO methods like, getAllModBusTags() which contains an instruction mapToBean(ModBusTag.class). Eventually all of the subclasses of Tag are fetched from the database (one fetch per protocol) and then added to an ArrayList of the supertype Tag.
My question is, is there a simple means with Jdbi to perform conditional mapping of rows so that if a row contains a specific value, it is mapped to ModBusTag.class but if a row contains a different value it is mapped to SNMPTag.class, and so on and so forth?
My end goal is to have a single select statement that fetches every tag from the database, automaps to the correct bean on a row by row basis and then stores all of these subclass beans in a List of the supertype Tag.
Example Method for Single Type:
#Override
public List<SNMPTag> getSNMPTags(){
try(Handle handle = daoFactory.getDataSourceController().open()) {
return handle.createQuery("SELECT * FROM dbo.Tags WHERE Active = 1 AND Protocol = 'SNMP'")
.mapToBean(SNMPTag.class)
.list();
}
catch(Exception e){
if(sysconfig.getVerbose()){ e.printStackTrace(); }
}
return null;
}
Some bad pseudocode to indicate what I want to do:
#Override
public List<Tag> getAllTags(){
try(Handle handle = daoFactory.getDataSourceController().open()) {
return handle.createQuery("SELECT * FROM dbo.Tags WHERE Active = 1")
.mapRows(row -> row.Protocol.equals("SNMP").mapToBean(SNMPTag.class)
.mapRows(row -> row.Protocol.equals("ModBus").mapToBean(ModBusTag.class)
//etc
.list();
}
catch(Exception e){
if(sysconfig.getVerbose()){ e.printStackTrace(); }
}
return null;
}
You can use RowMapper with some amount of custom code to achieve what you need, we successfully use such approach in our project. Here is simplified general example of this technique:
public class PolymorphicRowMapper implements RowMapper<Parent> {
#Override
public Parent map(ResultSet rs, StatementContext ctx) throws SQLException {
Type type = Type.valueOf(rs.getString("type"));
if (type == Type.A) {
return mapTo(rs, ctx, ChildA.class);
} else if (type == Type.B) {
return mapTo(rs, ctx, ChildB.class);
}
throw new IllegalStateException("Could not resolve mapping strategy for object");
}
private static <T extends Parent> T mapTo(
ResultSet rs,
StatementContext ctx,
Class<T> targetClass
) throws SQLException {
return ctx.getConfig().get(Mappers.class)
.findFor(targetClass)
.orElseThrow(() ->
new NoSuchMapperException(String.format("No mapper registered for %s class", targetClass))
)
.map(rs, ctx);
}
}
public static void main(String[] args) {
var jdbi = Jdbi.create("...")
.registerRowMapper(BeanMapper.factory(ChildA.class))
.registerRowMapper(BeanMapper.factory(ChildB.class));
try (Handle handle = jdbi.open()) {
handle.createQuery("SELECT * FROM table")
.map(new PolymorphicRowMapper());
}
}
public enum Type {
A, B
}
public abstract class Parent {
final Type type;
protected Parent(final Type type) {
this.type = type;
}
}
public class ChildA extends Parent {
public ChildA() {
super(Type.A);
}
}
public class ChildB extends Parent {
public ChildB() {
super(Type.B);
}
}
I cannot find a tutorial on this, and I find the documentation scant. How can I do batch insert using ibatis annotations?
public interface MyTableMapper {
#Insert("insert into MyTable(col1) values (#{valueOfCol1})")
void insert(MyRecordClass obj);
}
public class MyTransactionalClass {
#Transactional
public void insert(MyRecordClass obj) {
myTableMapperInst.insert(obj);
}
}
I did this naive implementation (surprisingly without success :-):
public class MyTransactionalClass {
#Transactional(executorType = ExecutorType.BATCH)
public void insert(MyRecordClass obj) {
myTableMapperInst.insert(obj);
}
}
This is without annotation, according to the docs, your way seems correct.
try {
sqlMap.startTransaction()
List list = (Employee) sqlMap.queryForList("getFiredEmployees", null);
sqlMap.startBatch ();
for (int i=0, n=list.size(); i < n; i++) {
sqlMap.delete ("deleteEmployee", list.get(i));
}
sqlMap.executeBatch();
sqlMap.commitTransaction();
} finally {
sqlMap.endTransaction();
}
iBatis annotation insert bulk record you can do like this
#Insert({"<script>",
"insert into user_master (first_name,last_name) values ",
"<foreach collection='userList' item='user' index='index' open='(' separator = '),(' close=')' >#{user.first_name},#{user.last_name}</foreach>",
"</script>"})
int insertUserList(#Param("userList") List<UserNew> userList);
It's work for me and i inserted bulk record in my PostgreSQL database using above single insert.
I'm implementing a Spring+ MSSQL Server 2008 application. I use SimpleJDBCCall API to execute stored procedures and retrieve results.
For stored procedures with mono table results, it works fine, but I don't know how to use it for procedures with multi table results.
here is the screenshot from query of my database that returns two result table.1
here is the code that i use,this code work properly with single table result`
public class LoadOnDemandSP extends StoredProcedure{
private static final String SPROC_NAME = "sps_IME_EF_GetAllMarketData";
public LoadOnDemandSP(DataSource ds) {
super(ds, SPROC_NAME);
RowMapper mapper = new MyRowMapper();
declareParameter(new SqlReturnResultSet("Return Value", mapper));
declareParameter(new SqlParameter("FromDate", Types.VARCHAR));
declareParameter(new SqlParameter("ToDate",Types.VARCHAR));
compile();
}
public List execute(String FromDate,String ToDate) {
Map inputs = new HashMap();
inputs.put("FromDate",FromDate);
inputs.put("ToDate",ToDate);
Map map = super.execute(inputs);
if (map != null && map.size() > 0) {
return (List) map.get("Return Value");
} else {
return new ArrayList();
}
}
private class MyRowMapper implements RowMapper<LoadOnDemand> {
public LoadOnDemand mapRow(ResultSet rs, int rowNum) throws SQLException {
LoadOnDemand l = new LoadOnDemand();
// f.setDay(rs.getInt("ContractDay"));
l.setInternalQuantity(rs.getInt("DVaznTon"));
l.setExportalQuantitiy(rs.getInt("SVaznTon"));
l.setInternalValue(rs.getDouble("DArzeshMillion"));
l.setExternalValue(rs.getDouble("SArzeshMillion"));
l.setInternalBuyersCount(rs.getInt("DBuyers"));
l.setExternalBuyersCount(rs.getInt("SBuyers"));
l.setInternalSellersCount(rs.getInt("DSellers"));
l.setExternalSellersCount(rs.getInt("SSellers"));
l.setInternalGoodsCount(rs.getInt("DSymbols"));
l.setExternalGoodsCount(rs.getInt("SSymbols"));
l.setTablo(rs.getString("GrouhAsli"));
return l;
}
}
}
///Added////
My sample SP:
CREATE PROCEDURE [dbo].[sps_Test1]
WITH RECOMPILE
AS
SELECT *
FROM dbo.tbl1
SELECT *
FROM dbo.tbl2
You could not handle the multiple tables. you can join the two tables as one by using either union or unionAll
CREATE PROCEDURE [dbo].[sps_Test1]
WITH RECOMPILE
AS
SELECT *
FROM dbo.tbl1
UNION
SELECT *
FROM dbo.tbl2
I'm a newbie with Hibernate, and I'm writing a simple method to return a list of objects
matching a specific filter. List<Foo> seemed a natural return type.
Whatever I do, I can't seem to make the compiler happy, unless I employ an ugly #SuppressWarnings.
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
public class Foo {
public Session acquireSession() {
// All DB opening, connection etc. removed,
// since the problem is in compilation, not at runtime.
return null;
}
#SuppressWarnings("unchecked") /* <----- */
public List<Foo> activeObjects() {
Session s = acquireSession();
Query q = s.createQuery("from foo where active");
return (List<Foo>) q.list();
}
}
I would like to get rid of that SuppressWarnings. But if I do, I get the warning
Warning: Unchecked cast from List to List<Foo>
(I can ignore it, but I'd like to not get it in the first place), and if I remove the generic to conform to .list() return type, I get the warning
Warning: List is a raw type. References to generic type List<E>
should be parameterized.
I noticed that org.hibernate.mapping does declare a List; but it is a different type altogether - Query returns a java.util.List, as a raw type. I find it odd that a recent Hibernate (4.0.x) would not implement parameterized types, so I suspect that it's me instead doing something wrong.
It looks very much like Cast Hibernate result to a list of objects, but here I have no "hard" errors (the system knows type Foo, and I'm not using a SQLQuery but a straight Query). So no joy.
I have also looked at Hibernate Class Cast Exception since it looked promising, but then I realized that I do not actually get any Exception... my problem is just that of a warning - a coding style, if you will.
Documentation on jboss.org, Hibernate manuals and several tutorials do not seem to cover the topic in such detail (or I didn't search in the right places?). When they do enter into detail, they use on-the-fly casting - and this on tutorials that weren't on the official jboss.org site, so I'm a bit wary.
The code, once compiled, runs with no apparent problem... that I know of... yet; and the results are the expected ones.
So: am I doing this right? Am I missing something obvious? Is there an "official"
or "recommended" Way To Do It?
Short answer #SuppressWarnings is the right way to go.
Long answer, Hibernate returns a raw List from the Query.list method, see here. This is not a bug with Hibernate or something the can be solved, the type returned by the query is not known at compile time.
Therefore when you write
final List<MyObject> list = query.list();
You are doing an unsafe cast from List to List<MyObject> - this cannot be avoided.
There is no way you can safely carry out the cast as the List could contain anything.
The only way to make the error go away is the even more ugly
final List<MyObject> list = new LinkedList<>();
for(final Object o : query.list()) {
list.add((MyObject)o);
}
The resolution is to use TypedQuery instead. When creating a query from the EntityManager instead call it like this:
TypedQuery<[YourClass]> query = entityManager.createQuery("[your sql]", [YourClass].class);
List<[YourClass]> list = query.getResultList(); //no type warning
This also works the same for named queries, native named queries, etc. The corresponding methods have the same names as the ones that would return the vanilla query. Just use this instead of a Query whenever you know the return type.
To answer your question, there is no "proper way" to do that.
Now if it's just the warning that bothers you, the best way to avoid its proliferation is to wrap the Query.list() method into a DAO :
public class MyDAO {
#SuppressWarnings("unchecked")
public static <T> List<T> list(Query q){
return q.list();
}
}
This way you get to use the #SuppressWarnings("unchecked") only once.
You can avoid compiler warning with workarounds like this one:
List<?> resultRaw = query.list();
List<MyObj> result = new ArrayList<MyObj>(resultRaw.size());
for (Object o : resultRaw) {
result.add((MyObj) o);
}
But there are some issues with this code:
created superfluous ArrayList
unnecessary loop over all elements returned from the query
longer code.
And the difference is only cosmetic, so using such workarounds is - in my opinion - pointless.
You have to live with these warnings or suppress them.
Only way that work for me was with an Iterator.
Iterator iterator= query.list().iterator();
Destination dest;
ArrayList<Destination> destinations= new ArrayList<>();
Iterator iterator= query.list().iterator();
while(iterator.hasNext()){
Object[] tuple= (Object[]) iterator.next();
dest= new Destination();
dest.setId((String)tuple[0]);
dest.setName((String)tuple[1]);
dest.setLat((String)tuple[2]);
dest.setLng((String)tuple[3]);
destinations.add(dest);
}
With other methods that I found, I had cast problems
List<Person> list = new ArrayList<Person>();
Criteria criteria = this.getSessionFactory().getCurrentSession().createCriteria(Person.class);
for (final Object o : criteria.list()) {
list.add((Person) o);
}
You use a ResultTransformer like that:
public List<Foo> activeObjects() {
Session s = acquireSession();
Query q = s.createQuery("from foo where active");
q.setResultTransformer(Transformers.aliasToBean(Foo.class));
return (List<Foo>) q.list();
}
The proper way is to use Hibernate Transformers:
public class StudentDTO {
private String studentName;
private String courseDescription;
public StudentDTO() { }
...
}
.
List resultWithAliasedBean = s.createSQLQuery(
"SELECT st.name as studentName, co.description as courseDescription " +
"FROM Enrolment e " +
"INNER JOIN Student st on e.studentId=st.studentId " +
"INNER JOIN Course co on e.courseCode=co.courseCode")
.setResultTransformer( Transformers.aliasToBean(StudentDTO.class))
.list();
StudentDTO dto =(StudentDTO) resultWithAliasedBean.get(0);
Iterating througth Object[] is redundant and would have some performance penalty.
Detailed information about transofrmers usage you will find here:
Transformers for HQL and SQL
If you are looking for even more simple solution you can use out-of-the-box-map-transformer:
List iter = s.createQuery(
"select e.student.name as studentName," +
" e.course.description as courseDescription" +
"from Enrolment as e")
.setResultTransformer( Transformers.ALIAS_TO_ENTITY_MAP )
.iterate();
String name = (Map)(iter.next()).get("studentName");
I found the best solution here, the key of this issue is the addEntity method
public static void testSimpleSQL() {
final Session session = sessionFactory.openSession();
SQLQuery q = session.createSQLQuery("select * from ENTITY");
q.addEntity(Entity.class);
List<Entity> entities = q.list();
for (Entity entity : entities) {
System.out.println(entity);
}
}
Just just using Transformers It did not work for me I was getting type cast exception.
sqlQuery.setResultTransformer(Transformers.aliasToBean(MYEngityName.class))
did notwork because I was getting Array of Object in the return list element not the fixed MYEngityName type of list element.
It worked for me when I make following changes When I have added sqlQuery.addScalar(-) each selected column and its type and for specific String type column we dont have to map its type. like addScalar("langCode");
And I have join MYEngityName with NextEnity we cant just select * in the Query it will give array of Object in the return list.
Below code sample :
session = ht.getSessionFactory().openSession();
String sql = new StringBuffer("Select txnId,nft.mId,count,retryReason,langCode FROM MYEngityName nft INNER JOIN NextEntity m on nft.mId = m.id where nft.txnId < ").append(lastTxnId)
.append(StringUtils.isNotBlank(regionalCountryOfService)? " And m.countryOfService in ( "+ regionalCountryOfService +" )" :"")
.append(" order by nft.txnId desc").toString();
SQLQuery sqlQuery = session.createSQLQuery(sql);
sqlQuery.setResultTransformer(Transformers.aliasToBean(MYEngityName.class));
sqlQuery.addScalar("txnId",Hibernate.LONG)
.addScalar("merchantId",Hibernate.INTEGER)
.addScalar("count",Hibernate.BYTE)
.addScalar("retryReason")
.addScalar("langCode");
sqlQuery.setMaxResults(maxLimit);
return sqlQuery.list();
It might help some one. in this way work for me.
In a project I'm a consultant I had this issue. See the solution:
First, I created the following method:
protected <T> MyTypedQuery<T> createNamedAliasQuery(final String queryName, final Class<T> type) {
final Query q = getSafeEntityManager().createNamedQuery(queryName);
q.unwrap(org.hibernate.Query.class)
.setResultTransformer(Transformers.aliasToBean(type));
return new MyTypedQuery<T>(q);
}
Second, I create a MyTypedQuery, which looks like a wrapper, as below:
public class MyTypedQuery<R> implements TypedQuery<R> {
private Query q;
public MyTypedQuery(Query q) {
this.q = q;
}
#Override
public int executeUpdate() {
return this.q.executeUpdate();
}
#Override
public int getFirstResult() {
return this.q.getFirstResult();
}
#Override
public FlushModeType getFlushMode() {
return this.q.getFlushMode();
}
#Override
public Map<String, Object> getHints() {
return this.q.getHints();
}
#Override
public LockModeType getLockMode() {
return this.q.getLockMode();
}
#Override
public int getMaxResults() {
return this.q.getMaxResults();
}
#Override
public Parameter<?> getParameter(String arg0) {
return this.q.getParameter(arg0);
}
#Override
public Parameter<?> getParameter(int arg0) {
return this.q.getParameter(arg0);
}
#SuppressWarnings("unchecked")
#Override
public <T> Parameter<T> getParameter(String arg0, Class<T> arg1) {
return (Parameter<T>) this.q.getParameter(arg0);
}
#Override
public <T> Parameter<T> getParameter(int arg0, Class<T> arg1) {
return (Parameter<T>) this.q.getParameter(arg0, arg1);
}
#Override
public <T> T getParameterValue(Parameter<T> arg0) {
return (T) this.q.getParameterValue(arg0);
}
#Override
public Object getParameterValue(String arg0) {
return this.q.getParameterValue(arg0);
}
#Override
public Object getParameterValue(int arg0) {
return this.q.getParameterValue(arg0);
}
#Override
public Set<Parameter<?>> getParameters() {
return this.q.getParameters();
}
#Override
public boolean isBound(Parameter<?> arg0) {
return this.q.isBound(arg0);
}
#Override
public <T> T unwrap(Class<T> arg0) {
return this.q.unwrap(arg0);
}
#SuppressWarnings("unchecked")
#Override
public List<R> getResultList() {
return (List<R>) this.q.getResultList();
}
#SuppressWarnings("unchecked")
#Override
public R getSingleResult() {
return (R) this.q.getSingleResult();
}
#Override
public TypedQuery<R> setFirstResult(int arg0) {
this.q.setFirstResult(arg0);
return this;
}
#Override
public TypedQuery<R> setFlushMode(FlushModeType arg0) {
this.q.setFlushMode(arg0);
return this;
}
#Override
public TypedQuery<R> setHint(String arg0, Object arg1) {
this.q.setHint(arg0, arg1);
return this;
}
#Override
public TypedQuery<R> setLockMode(LockModeType arg0) {
this.q.setLockMode(arg0);
return this;
}
#Override
public TypedQuery<R> setMaxResults(int arg0) {
this.q.setMaxResults(arg0);
return this;
}
#Override
public <T> TypedQuery<R> setParameter(Parameter<T> arg0, T arg1) {
this.q.setParameter(arg0, arg1);
return this;
}
#Override
public TypedQuery<R> setParameter(String arg0, Object arg1) {
this.q.setParameter(arg0, arg1);
return this;
}
#Override
public TypedQuery<R> setParameter(int arg0, Object arg1) {
this.q.setParameter(arg0, arg1);
return this;
}
#Override
public TypedQuery<R> setParameter(Parameter<Calendar> arg0, Calendar arg1, TemporalType arg2) {
this.q.setParameter(arg0, arg1, arg2);
return this;
}
#Override
public TypedQuery<R> setParameter(Parameter<Date> arg0, Date arg1, TemporalType arg2) {
this.q.setParameter(arg0, arg1, arg2);
return this;
}
#Override
public TypedQuery<R> setParameter(String arg0, Calendar arg1, TemporalType arg2) {
this.q.setParameter(arg0, arg1, arg2);
return this;
}
#Override
public TypedQuery<R> setParameter(String arg0, Date arg1, TemporalType arg2) {
this.q.setParameter(arg0, arg1, arg2);
return this;
}
#Override
public TypedQuery<R> setParameter(int arg0, Calendar arg1, TemporalType arg2) {
this.q.setParameter(arg0, arg1, arg2);
return this;
}
#Override
public TypedQuery<R> setParameter(int arg0, Date arg1, TemporalType arg2) {
this.q.setParameter(arg0, arg1, arg2);
return this;
}
}
Third (and last), the use is straightforward like:
final List<Car> list =
createNamedAliasQuery("your-named-query", Car.class)
.setParameter("idCar", idCar)
.setParameter("idModel", idModel)
.getResultList();
Note that #SuppressWarnings("unchecked") appears once in our MyTypedQuery and not in every single use.
First of you have ensure the naming in HQL.
Use the name of the entity in the HQL query.
If you don't specify any name in the #Entity annotation then the default is your class name.
For More Information:
https://javabydeveloper.com/org-hibernate-hql-internal-ast-querysyntaxexception-entity-table-is-not-mapped/