Find by id=1 spring data jpa - spring

I have a table component and entity Component. I want to select id = 1 record from jpa query. Can I write 'findByIdOne' or 'findByIdEqualtoOne'? will that give me id = 1 record? Please let me know, Thanks.

No, you cannot. Refer to the Spring Data JPA documentation which documents the exact keywords that you can use.
You are free to specify the query that you want a method to execute though. Something like
#Query("select c from Component c where c.id=1")
Component findByIdOne();
I do have to put a disclaimer: by providing this solution I assume that you are really sure that ID 1 is always going to exist and will always point to exactly the same Component record in any environment that you may be running the application against. Hardcoded database IDs in your application code is not something I would ever recommend.

Direct writing the query dsl you cant, but there is a 'way' with Java 8 using default methods:
Let's say you have the query:
public interface ComponentRespository extends CrudRepository<Component, Long> {
#Query("select c from Component c where c.id=:id")
Component findById(#Param("id") Long id);
default Component findByIdOne() {
return findById(1L);
}
//eventually
default Component findByIdTwo() {
return findById(2L);
}
}
This way you can use:
private ComponentRespository componentRepository;
.....
Component componentOne = componentRepository.findByIdOne();
Component componentTwo = componentRepository.findByIdTwo();

You can use Optional<EntityName> findById(long id) or List<EntityName> findById(long id) if it's not unique.

You can use Optional<EntityName> findById(long id) or List<EntityName> findAllById if it's not unique.
We have several options:
findByIdIs(long id) or findByIdEquals(long id)

Related

How to fetch multiple entities by a list of natural ids with Hiberate or JPA repository?

If I have a list of natural Ids, how can I fetch all the records in the DB associated with these natural Ids at once?
All I've seen are methods that let you find an entity by a natural Id, an example of one is shown below.
#Override
public Optional<T> findBySimpleNaturalId(ID naturalId) {
Optional<T> entity = entityManager.unwrap(Session.class)
.bySimpleNaturalId(this.getDomainClass())
.loadOptional(naturalId);
return entity;
}
I am looking for a method that can take a list natural Ids and fetch all the entities with these natural Ids. My current Entity has a autogenerated UUID and a naturalId and I'd like to keep it this way.
Is there something like this below
List<Song> songs = entityManager
.unwrap(Session.class)
.byMultipleSimpleNaturalIds(Song.class)
.multiLoad(songGroup.getSongIds());
// or using the repository
customRepository.findAllByNaturalId(...)
The examples you've seen are showing you how to build them yourself, as spring does not provide individual methods for you; it knows nothing about properties in your entity other than it must have an id. If you want a findAllByNaturalId method, you have to define it in the interface.
Specifying this in your customRepository:
public List<Song> findByNaturalIdIn(List<Int> naturalIds);
Spring should generate an implementation that creates a query similar to "Select s from Song s where s.naturalId In :naturalIds".
If it doesn't, just add that JPQL query string as an annotation and it will execute it for you:
#Query(value = "Select s from Song s where s.naturalId In :naturalIds")
public List<Song> findByNaturalIdIn(List<Int> naturalIds);
Or you can write your own implementation method to execute your loadOptional calls, or any query you wish, but you still must define the method in your repository.

How to connect three tables using only one entity/class in Spring & Hibernate

I have only one entity which is School - a class (example). I have 7 fields in there and those fields are from 3 different tables. The first table for example is called Classroom, second is the Teachers, third is Subject. The teachers and subject table are connected by a pk: subject_id while the classroom table and teachers table are connected by classroom_id.
I tried secondary tables but it looks like it's not correct. How to connect those tables inside a single entity and write a query in the DAO IMPLementation
You should use Entity per Table.
If you need to select into non database related Model class, you can be done easily with spring-data-jpa.
After create the Model class (like School) just use the following sample to query:
class ProgrammerNameAndCity{
fields...
allArgConstructor...
}
public interface ProgrammerRepository extends JpaRepository<Programmer,Long> {
#Query(" select new com.zlrx.database.pojo.ProgrammerNameAndCity(p.name,p.address.city) " +
"from Programmer p where p.idNumber=?1")
ProgrammerNameAndCity findNameAndCityByIdNumber(String idNumber);
}
In this example the programmer has an address field (OneToOne), but you can create any kind of query, the important thing here is the constructor call of the model.
If you want to use plain sql or impl class instead of interface to query, you can use Spring's RowMapper too.
class ProgrammerNameAndCity{
fields...
allArgConstructor...
}
public interface ProgrammerRepository extends JpaRepository<Programmer,Long> {
#Query(" select new com.zlrx.database.pojo.ProgrammerNameAndCity(p.name,p.address.city) "
+ "from Programmer p where p.idNumber=?1")
ProgrammerNameAndCity findNameAndCityByIdNumber(String idNumber);
}

How to Return all instances of the type with the given ID in JPA SpringBoot?

I'm trying to return (or fetch) all the records from the database based on an ID provided by me. I'm using JPA and i'm aware of findAll() method but it returns all the records without any criteria, I created a custom query and it is only returning a unique value from the table but i want to return all records based on a criteria.
For example, findAllByUserID(String UserID) method should return all the records based on that UserID not just one.
I'd appreciate any help or suggestion.
Thanks
Have a look at the doc. There you will find the keywords you can use to declare methods in repository interfaces that will generate the according queries:
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods
In your case: If userID is an attribute of your entity you can add a method
List<YourEntity> findByfindAllByUserID(String userId)
to your repository interface.
First, make sure that you're not using any aggregate function in your select query such as DISTINCT()
Then make sure that the the method which is implementing that query is returning a List of you're desired result.
here's how it should look :
#Query("select t from table t where t.code = ?1")
List<Result> findAllByUserID(String UserID);

How to update a row by id in jpa hibernate?

I was trying to update a row in db by fetching the idByName, but instead it's adding a new row? Please help me out.
This is my controller code:
#PostMapping("/retailer/update")
public ModelAndView updateRetailer(#ModelAttribute("retailer") Retailer retailerDetails)
{
System.out.println(retailerDetails.toString());
System.out.println("method called");
UUID id=repository.findIdByName(retailerDetails.getBusinessName());
System.out.println(retailerDetails.getBusinessName());
System.out.println(id);
String name=retailerDetails.getBusinessName();
System.out.println(name);
//Retailer retailer=repository.findOne(rid);
if(id == null)
{
return null;
}
retailerDetails.setBusinessName(retailerDetails.getBusinessName());
retailerDetails.setCity(retailerDetails.getCity());
retailerDetails.setIsActive(retailerDetails.getIsActive());
retailerDetails.setStartDate(retailerDetails.getStartDate());
retailerDetails.setUrl(retailerDetails.getUrl());
repository.save(retailerDetails);
return new ModelAndView("welcome");
}
This is my Repository code:
public interface RetailerRepository extends JpaRepository<Retailer, UUID>{
#Query("SELECT r.id FROM Retailer r where r.businessName=:name")
UUID findIdByName(#Param("name") String name);
}
You should forget to set the "id" to the retailerDetails entity. Spring JPA will only execute the update action when the primary key is set.
Added the following line in your code.
retailer.setId(id);
repository.save(retailer);
You should simply fetch by BusinessName.
Repository method be:
Retailer findByBusinessName(#Param("name") String name);
updateRetailer method be like:
Retailer retailer = findByBusinessName(retailerDetails.getBusinessName());
if(retailer!=null){
retailer.setBusinessName(retailerDetails.getBusinessName());
retailer.setCity(retailerDetails.getCity());
retailer.setIsActive(retailerDetails.getIsActive());
retailer.setStartDate(retailerDetails.getStartDate());
retailer.setUrl(retailerDetails.getUrl());
repository.save(retailer);
}
Your controller looks great and so is your repository. There is something that you should know when it comes to updating an entity with hibernate. Hibernate will save(create new object) if the id for the given item is null during the transaction and hibernate will save(update the current instance in the database) if the id exist.
The flow for this update I presume is when the request to update is requested, you retrieve the object based on the specified entity then return to the view. One thing to take note of is to carry your id with your even in the view.
Make sure you include the id in a hidden input like
from there the id will be submitted in addition to the updated data to the post method.
Most update issues similar to this can be fixed by versioning entity with the #Version
Use the format of the Spring Data JPA to successfully query without writing any query.
#Repository
public interface RetailerRepository extends JpaRepository{
// Assuming there is an attribute businessName in the Retailer entity.
UUID findByBusinessName(String businessName);
}

Incorrect derived query for byId in Spring Data Neo4j

I have two entities: User and Connection, along with two appropriate repositories. Both entities has #GraphId id field. Connection entity has User user field.
In ConnectionRepository interface I added following method:
List<Connection> findByUserId(long userId)
But it doesn't work. It generates incorrect cypher query. I think it incorrect, because it contains clause like this:
WHERE user.id = 15
which is not working, because id is not a property. It must be:
WHERE id(user) = 15
Is this a bug? In any case, how can I get it to work?
The derived query translates to the property id of the user defined on the Connection. It is quite possible that node entities contain a user managed id property as well and it would be incorrect to assume that id is always the node id.
In this case, you might want to use a #Query instead.
#Query("MATCH (user:label) WHERE ID(user)={0} return user")
List<Connection> findByUserId(long userId)

Resources