I used SpEL for generic entity name in my Spring Data JPA repositories. This time, I need to join 2 tables via JPQL and for this purpose, I am wondering if I can use multiple entity by passing to the repository and then using it in my query as SpEL 's ${#entityName}. So, is it possible?
DiningRepository:
#Query("select d as dining, dg as diningGroup, s as site " +
"from Dining d " +
" join DiningGroup dg on d.groupUuid = dg.uuid " +
" join Site s on dg.siteUuid = s.uuid " +
"where d.uuid = :uuid")
Optional<GroupAndSiteProjection> findByUuid(#Param("uuid") UUID uuid);
Here is projection where I collect Dining, DiningGroup and ``Site` result:
public interface GroupAndSiteProjection {
Dining getDining();
DiningGroup getDiningGroup();
Site getSite();
}
The method is in DiningRepository and ${#entityName} gets Dining entity. But I want to use also DiningGroup by passing it to the repository as generic e.g. DiningRepository<Dining, DiningGroup>... Is it possible?
Related
in code like this
#Query("select se.id from someEntity se"
+ " inner join se.anotherOne ao"
+ " inner join se.lazyOne l"
+ " where l.someField = true")
Should I use "fetch" to get someFiled from lazy entity or Hibernate/Jpa/Spring Data/God will do it for me?
It is not necessary as you pose the query, you could do the following:
#Query("select se.id, ao.id, l.id from someEntity se"
+ " inner join se.anotherOne ao"
+ " inner join se.lazyOne l"
+ " where l.someField = true")
And indicate as the class returned when executing the query a pojo with a constructor that matches in order and type with the parameters of the select clause as follows:
public YourPojo(Long idSomeEntity, Long idAnotherOne, Long idLazyOne){
//Object construction
}
The use of fetch would be for example if you wanted to bring you a list of someEntity entities with their lazyOne property fed
#Query("select se from someEntity se"
+ " join fetch se.anotherOne ao"
+ " join fetch se.lazyOne l"
+ " where l.someField = true")
That depends. If you JOIN FETCH lazy field, hibernate won't run another query to fetch it later. Otherwise when accessing this field, hibernate will have to query database for it. It's more of optimization thing.
I have this query for Oracle and i must convert in HQL (Hibernate Query Language). I haven't found information on convert key words like "START WITH" or "CONNECT BY PRIOR" or "SINBLINGS".
can you help me ?
The Query is this:
SELECT NOME_PADRE, COD_PADRE, NOME_FIGLIO, COD_FIGLIO,
CONFIRM_COD_FIGLIO, LEVEL
FROM (
SELECT s1.NOME AS NOME_PADRE, a.PADRE AS COD_PADRE, s2.NOME AS
NOME_FIGLIO, a.CMU AS COD_FIGLIO, s2.CMU AS
CONFIRM_COD_FIGLIO
FROM ALBERO a JOIN STRUTTURE s1 ON a.PADRE = s1.CMU
JOIN STRUTTURE s2 ON a.CMU = s2.CMU
ORDER BY PADRE ASC
)
START WITH COD_PADRE = '00000'
CONNECT BY PRIOR COD_FIGLIO = COD_PADRE
ORDER SIBLINGS BY COD_PADRE
Thank you very much
I tried to use a native query.
I use Spring-Boot and i have a Controller, a Service and a Repository.
In my repository, I implement a native query like this:
String QUERY = " SELECT s.CMU, s.NOME, a.PADRE, LEVEL "
+ " FROM STRUTTURE s LEFT JOIN ALBERO a ON s.CMU = a.CMU "
+ " START WITH a.PADRE = '00000' "
+ " CONNECT BY PRIOR a.CMU = a.PADRE "
+ " ORDER SIBLINGS BY a.PADRE";
#Query(nativeQuery = true, value = QUERY)
public List<Struttura> findAllWithConnectBy();
but I have this error:
org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name 'strutturaController': Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)
I have one entity and a one to one relationship. Now i'm looking for the best way to retrieve specific fields from both tables using a projection.
In my first attempt i've tried:
"SELECT NEW br.com.domain.order.Order( " +
"o.id," +
"o.description," +
"p.payment) " +
"FROM Order o
Using this way i have a single constructor inside Order entity, to retrieve only these 3 fields. But now i have N+1 queries.
The second option is the follow:
"SELECT NEW br.com.domain.order.OrderDTO( " +
"o.id," +
"o.description," +
"p.status,
p.locationId,
p.value) " +
"FROM Order o JOIN o.payment p
This works great but i have to create a DTO class.
How can i do something like this:
"SELECT NEW br.com.domain.order.Order( " +
"o.id," +
"o.description," +
"p.status,"+
"p.locationId,"+
"p.value)"
It's necessary to create a constructor inside both entities to load all properties?
How do I accomplish this custom sort by field feature available in MySQL in hibernate?
select * from pet order by field(species, 'cat', 'dog', 'bird');
For some business reason, I need to enforce a custom ordering.
PS -I am new to hibernate.
I ended up writing an HQL like this
commaDelimitedSpecies = "'cat', 'dog', 'bird'";
orderBySpecies = " ORDER BY FIELD(species, " + commaDelimitedSpecies + ") DESC";
Query q = getSession().createQuery("FROM PetModel pet" + orderBySpecies);
With Spring HibernateDAO:
getHibernateTemplate().findByNamedParametersQuery(
"FROM MyEntity me WHERE me.id IN :ids ORDER BY FIELD(id, :ids)", new String[] {"ids"}, new Object[] {uuidList.toArray()},uuidList.size()
);
Note: getHibernateTemplate returns an instance of org.springframework.orm.hibernate3.HibernateTemplate
Currently I have such piece of code, which doesn't work, since I have to add schema name before each table in a query(like DEV.DASHBOARDS_METADATA):
public interface DashboardMetadataDao extends CrudRepository<DashboardMetadata, Integer> {
#Query("SELECT D FROM DASHBOARDS_METADATA D " +
"INNER JOIN FAC_DASHBOARDS_LINK DL ON D.ID = DL.DASHBOARD_ID " +
"INNER JOIN FIRMS F ON DL.FAC_ID = F.FAC_UNIT_ID " +
"INNER JOIN USERS U ON U.FIRM_ID = F.FIRM_ID WHERE LOWER(U.USERID) = LOWER(:userid)")
public Set<DashboardMetadata> findByUserId(#Param("userid") String userId);
}
The problem is that schema name differs from database to database (DEV/QA/PROD). Normally I use component's method which prepend schema's name to each table during query generation. How can do this using annotations?
Thanks!
Hibernate has a variable that can be used in native queries to get schema name called: {h-schema}
https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/query/native/Native.html#sql-global-catalog-schema You can just put {h-schema}table in your query. I think you have to convert it to a native query.
Below Code Snippet worked for me
#Query(
value = "select *\n" +
"from {h-schema}TABLE-A r left join {h-schema}TABLE-B p on r.ID=p.ID\n" +
"left join {h-schema}TABLE-C pe on p.ID=pe.ID\n" +
"left join {h-schema}TABLE-D e on pe.ENT_ID=e.ENT_ID\n" +
"where r.role_type='Provisioning'",
nativeQuery = true)