How to retrieve only values of a single column in Crud Repository in Springboot from method Names without using #Query Annotation? - spring-boot

I need to retrieve distinct values of a particular column in CrudRepository in Springboot without using #Query annotation.

A single value is not possible but you could use interface-based projections:
For example if you need only the name of a table:
interface NameOnly {
String getName();
}
interface PersonRepository extends Repository<Person, UUID> {
Collection<NameOnly> findByLastname(String lastname);
}
Read more here:
https://docs.spring.io/spring-data/jpa/docs/2.1.4.RELEASE/reference/html/#projections

Related

How to get the specific property value from .properties file in Spring Data Repository interface method #Query

I am able to get the property value in Spring classes like below:
#Value("${database.name}")
private String databaseName;
I have to execute a native query by joining different tables which are in different databases.
#Query(value="select t1.* FROM db1.table1 t1 INNER JOIN db2.table2 t2 ON t2.t1_id1 = t1.id1")
Instead of hard coding database names i.e., db1 and db2 here, I have to get them from properties file.
how to get the property value inside the #Query annotation in Spring Data JPA Repository ?
I don't know if it is possible, but if not, you can consider this approach:
Instead of using properties in Repository's #Query directly, you can use params in the query but when you call the actual method - you can provide values from .properties.
Imagine you have simple repository:
public interface UserRepository extends JpaRepository<User, Long> {
// query with param
#Query("select u from User u where u.lastname = :lastname")
User findByLastname(#Param("lastname") String lastname);
}
Then, let's say you have some Service or Controller where you need to use your Repository - you can inject properties there and pass them to your method:
#Service
public class UserService {
// this comes from .properties
#Value("${user.lastName}")
private String userLastName;
#Autowired
private UserRepository userRepository;
public User getUser() {
// you pass it as param to the repo method which
// injects it into query
return userRepository.findByLastname(userLastName);
}
}
This is just an example. But I believe it may be useful.
Happy hacking :)

Spring Boot 2.0.0.M2/Spring Data and findById method

I'm trying to move my project to Spring Boot 2.0.0.M2
Now Spring Data uses Optional for findBy* methods, like:
Optional<T> findById(ID id);
I have a Neo4j entities that contain the id property, for example:
#NodeEntity
public class Tag {
private Long id;
}
#Repository
public interface TagRepository extends Neo4jRepository<Tag, Long>
Tag findById(Long tagId);
}
id is a plain property and not and entity identifier(PK).
Prior Spring Boot 2.0 I used repository.findOne() embedded method in order to look up entity by it's identifier(PK) and my custom repository.findById() in order to look up entity by its id property.
Right now with Spring Boot 2.0 we don't have findOne and instead of this we have findById method finds the entity by PK. Right now I don't know how to provide my custom repository.findById method i order to be able to look up entity by ID property(not PK). Please advise.
If the field tagId exists in the entity you can use
Tag findByTagId(long tagId);
if not use
#Query("select t from Tag t where t.tagId = :tagId")
Tag getByTagId(#Param("tagId") long tagId);

How to Define Dynamic Model in Spring Framework

I am using Spring Framework as my back end
I have define know as Entity class The Entity class know contain 5 Fields
Below is the class , The code below dose not have setter getter part to make shorter and cleaner
#Entity
#Table(name="TblKnow")
public class Know {
#Id
private Double idKnow;
private String SubjectKnow;
private String BodyKnow;
private String ImgKnow;
private double CountView;
In JpaRepository interface i want to only query two column not all of columns.
public interface KnowRepository extends JpaRepository<Know,Double> {
#Query("SELECT idKnow,SubjectKnow FROM Know")
public Page<Know> findCByOrderByIdKnowDesc(Pageable pageable);
Problem: i try to run but i get below exception
java.lang.IllegalArgumentException: Cannot create TypedQuery for query with more than one return using requested result type [java.lang.Long]
But if i use without below query it is fine
public Page<Know> findAllByOrderByIdKnowDesc(Pageable pageable);
You can create a custom constructor and use that to select only some fields in JPA query.
public Know(Double idKnow, String SubjectKnow) {
this.idKnow = idKnow;
this.SubjectKnow = SubjectKnow;
}
And the use this constructor in JPA query. Make sure you use complete path of class with package.
#Query("SELECT NEW packagePath.Know(idKnow,SubjectKnow) FROM Know")
query :
public Page<Know> findAllByOrderByIdKnowDesc(Pageable pageable);
works dut to you select Know objects with fields that are mapped correct into Know class (and after wrapped into Page).
with query :
#Query("SELECT idKnow,SubjectKnow FROM Know")
public Page<Know> findCByOrderByIdKnowDesc(Pageable pageable);
returns some custome bean/object that spring data can't map in correct way into Know class (as you declared it as expected return class wrapped into Page). add counstructor into Know with idKnow,SubjectKnow fields , or you can wrap it into some DTO with idKnow,SubjectKnow fields.

SpringData findAll is processing all database tables and not the one requested

I am new to SpringData and I am not getting what is happening here. I have created an Interface that extends PagingAndSortingRepository and overrided the findAll() method like this:
#Override
#Query
List<MyEntity> findAll();
I am calling this method in my service, but it is making my app to throw an exception Caused by: java.lang.StackOverflowError because that method is reading through the entire database, not only from MyEntitytable in database. Any idea?
Apparently the problem is in the configuration of EclipseLink. In persistence.xml I added this row <shared-cache-mode>NONE</shared-cache-mode> and now it works as it should.
no need to override getall() method.in your service autowired that dao or repository class and using this you can directly call the findall() method.
in the case you want to write your custom method apart from what given by spring data jpa then we use the #Query to write custom query.
No Need to Override. What i have done is i have created a repository i.e
FavoriteRepository which is extending JpaRepository and i have mentioned the
dbmodel name (Favorite)
like this JpaRepository<Favorite, Long> // Here Favorite is my model name
and Long is the type of primary key mentioned in db model Favorite as #Id
#Repository
public interface FavoriteRepository extends JpaRepository<Favorite, Long>{
}
Now you can use method findOne or findAll. As these methods are present in
Jparepository.Hope so it will help
If you want to add new method then use #Query with JpQL
#Query(value = "select f from Favorite f where f.userId=:userId ")
public List<Favorite> getFavoritesForUser(#Param("userId") String userId);

#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