does JPQL not have an * symbol? - spring-boot

#Repository
public interface ParticipantRepository extends CrudRepository<Participant,Integer> {
#Query("select e from Participant e WHERE e.event.venue =:venue")
List<Participant> getParticipantsByEventVenue(String venue);
}
As you can see here ^ I have to use e to represent the * symbol. Is that just how JPQL works?
is there an * symbol in JPQL?

Yes, it is particular syntax for JPQL. But if you like to use native SQL query, it is also possible as follows:
#Repository
public interface ParticipantRepository extends
JpaRepository<Participant,Integer> {
#Query("select * from Participant e WHERE
e.event.venue =:venue",nativeQuery = true)
List<Participant> getParticipantsByEventVenue(String venue);}
also it is recommender to use JpaRepository instead of crudRepository.

Related

How can I get a sequence number from an oracle database with jpaRepository?

I´m trying to get a sequence number from an oracle database using a jpaRepository.
The main problem is because I don´t have any Object in JpaRepository so I don´t really know how to solve it. The sequence number will be a Long, and I only need to return this number in my repository.
My code:
#Repository
public interface InsuranceRepository extends JpaRepository<Long, Long> {
#Query(value = "SELECT INSURANCE_VOUCHER_SEQ.nextval FROM dual", nativeQuery = true)
Long findInsuranceVoucher();
}
I know is wrong, but I don´t know how I should implement it.
Thanks everyone.
You could theoretically do it, but it will be ugly. How about using #PersistenceContext like so:
#Repository
public class InsuranceDao {
#PersistenceContext
private EntityManager entityManager;
public Long getInsuranceVoucher() {
Query q = entityManager.createNativeQuery("SELECT INSURANCE_VOUCHER_SEQ.nextval FROM dual");
return (Long) q.getSingleResult();
}
}
One workaround is to make a dummy entity that refers to the pseudo-table dual (I see the Oracle tag).
#Entity
public class Dual {
#Id
private String dummy;
/* ... boilerplate ... */
}
Then use this entity in your repository.

select distinct values using spring data rest

I'm using java 8 and spring-data-rest to create API on my data.
I have a table Car(id, name, date...)
I'm trying to have an endpoint to retrieve distinct car names.
here's my Repository :
#RepositoryRestResource(path = "cars")
public interface CarRepository extends JpaRepository<Car, Long> {
//What i want to do
//#Query(value = "select distinct c.name as name from Car c")
#Query(value = "select distinct c from Car c")
List<Car> findDistinctName();
}
The query commented does not work , i have an exception
java.lang.IllegalArgumentException: PersistentEntity must not be null!
apparently this is the normal behavior of SDR.
I tried another solution by using Projections
#Projection(name = "name", types = {Car.class})
public interface CarName {
String getName();
}
but i cant get the distinct values, any idea?
Thank you :)
All you need, to do if you need a distinct list of cars, is such this query method:
public interface CarRepository extends JpaRepository<Car, Long> {
List<Car> findDistinctBy();
}
Spring Data JPA supports the Distinct keyword in repository query methods to set a distinct flag on the query to be created.
I found an (ugly) workaround, using jpql :
#Query(value = "select c from Car C WHERE c.id IN (SELECT min(ca.id) FROM Car ca Group by ca.name)")
I think you should remove the #Query annotation.
Just
List<Car> findDistinctName(); or List<Car> findNameDistinct(); should suffice.
It will automatically generate the query select c.name from Car c

Hibernate JPA issue doesnt apply IS-A Relationship of table at some times

I have a Parent Table A and extended Child tables B and C
ex:
public class A {
private Long id;
//getters setters//
}
public class B extends A{
private String name;
//getters setters//
}
now at my repository,
public interface B extends JpaRepository<B, Long> {
#Query("select a from A a")//--This works
B getAll()
#Query("select a.id, b.name from A a join a.B b")//-- This doesn't
B getSpecificCols()
}
I need an explanation since "B is an A" that's why getAll() works
how come getSpecificCols() isn't working?
Error is
java.lang.ClassCastException: java.lang.Long cannot be cast to <package>.B
BTW I'm using Hibernate Spring
The query returns a long (a.id) and a string (b.name). The interface assumes that you return an entity (B). The returned id cannot be cast into a B, so you get a ClassCastException. If you want individual fields you can return List<Object[]>, where each record will be an array with id and name. Or you can use a projection (https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections).
By the way, does the first query really work when there are A entities in the database that are not B entities, for example if A also has a subclass C? It looks plain wrong to select the base class and return the derived class without filtering. I would select from B to return B.
After reading documentation what I needed all along was to put constructors in my entity/table where you put what specific parameters you need.

How to select object by another object's field

I have a 2 entity - Klient and DocAcc. For access to my data I use Spring Data. Here is my repository:
public interface DocAccRepository extends CrudRepository<DocAcc, Long> {
#Query("select d from DocAcc d where d.sals = klient.sals")
List<DocAcc> findByKlient(Klient klient);
}
this code didn't work. Error:
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Invalid path: 'klient.sals' [select d from vap.entity.DocAcc d where d.sals = klient.sals]
My entity wired more than one field. How can I acces to object parameters inside Query?
You can use SpEL expressions in #Query
public interface DocAccRepository extends CrudRepository<DocAcc, Long> {
#Query("select d from DocAcc d where d.sals = :#{#klient.sals}")
List<DocAcc> findByKlient(#Param("klient") Klient klient);
}
More info here: https://spring.io/blog/2014/07/15/spel-support-in-spring-data-jpa-query-definitions

#NamedQuery override findAll in Spring Data Rest JpaRepository

Is there a way to override the findAll query executed by Spring Data Rest?
I need a way of filtering the results based on some specific criteria and it seems that using a #NamedQuery should be along the lines of what I'm looking for so I setup a test.
#Entity
#Table(name = "users")
#NamedQueries({
#NamedQuery(name = "User.findAll", query="SELECT u FROM User u WHERE u.username = 'test'"),
#NamedQuery(name = "User.findNameEqualsTest", query="SELECT u FROM User u WHERE u.username = 'test'")
})
public class User implements Serializable, Identifiable<Long> { }
With this in place I would expect SDR to utilize my findAll() query (returning 1 result) but instead it executes the same old findAll logic (returning all results).
In my Repository I added:
#Repository
#RestResource(path = "users", rel = "users")
public interface UserJpaRepository extends JpaRepository<User, Long> {
public Page<User> findNameEqualsTest(Pageable pageable);
}
and in this case it DOES pick up the provided #NamedQuery. So...
How should I go about overriding the default findAll() logic? I need to actually construct a complex set of criteria and apply it to the result set.
In the upcoming version 1.5 (an RC is available in our milestone repositories) of Spring Data JPA you can simply redeclare the method in your repository interface and annotate it with #Query so that the execution as query method is triggered. This will then cause the named query to be looked up just as you're already used to from query methods:
interface UserJpaRepository extends PagingAndSortingRepository<User, Long> {
#Query
List<User> findAll();
Page<User> findNameEqualsTest(Pageable pageable);
}
A few notes on your repository declaration:
You don't need to annotate the interface with #Repository. That annotation doesn't have any effect at all here.
Your #RestResource annotation configures the exporter in a way that will be the default anyway in Spring Data REST 2.0 (also in RC already). Ging forward, prefer #RestRepositoryResource, but as I said: the pluralization will be the default anyway.
We generally don't recommend to extend the store specific interfaces but rather use CrudRepository or PagingAndSortingRepository.
Yes, you can create your Implementation of your Repository interface, there is acouple section in
http://docs.spring.io/spring-data/jpa/docs/1.4.3.RELEASE/reference/html/repositories.html#repositories.custom-implementations
Repository
#Repository
public interface PagLogRepository extends JpaRepository<PagLogEntity, Long>, PagLogCustomRepository {
Custom Interface
public interface PagLogCustomRepository {
PagLogEntity save(SalesForceForm salesForceForm) throws ResourceNotFoundException;
Custom implementation
public class PagLogRepositoryImpl implements PagLogCustomRepository {
#Override
public PagLogEntity save(final SalesForceForm salesForceForm) throws ResourceNotFoundException {
query = emEntityManager.createNamedQuery("findItemFileByDenormalizedSku", ItemFileEntity.class);
query.setParameter("skuValue", rawSku);
Instead of override save make it with findAll, then you can create complex customization

Resources