Fetching list of records based on list of Primary Key using Spring Data JPA - spring

I need to fetch multiple records by querying on multiple Primary Keys. For instance, fetching multiple Employee records from Oracle DB
having fields as EmployeeId, EmployeeName based on multiple Primary key employee_id = {1,2,3} which will result in 3 Employee records, all within a single DB session.
I can do it one by one :
Optional<EmployeeBean> eb = employeeRepo.findByEmployeeId(Id);
Here employeeRepo extends CrudRepository<Employee, Long>
Is it possible to do batch wise record fetch with list of Primary Keys in Spring 5?

Use findByEmployeeIdIn(List<Long> ids). Here is a list of keywords you can use with spring data jpa.

Related

How to bulk delete from a JPA repository in Spring Data receiving a list filled with one of the properties from my Entity class

I have an Entity that has four properties, (vehicle, unit, date and id). Primary key is the ID.
I want to delete rows from the database based on the vehicle list provided to me via a request body.
How can I take all the lists and use them to delete data from the database at once?
You can create a "delete...By" query in your Entity repository that takes a List of Vehicle as a parameter and deletes all entities that their Vehicle is contained in that List.
Something like this should work:
void deleteAllByVehicle(List<Vehicle> vehicles);
The documentation contains more options:
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods
you can use JPQL to provide custom query
#Query(delete from Entity e where e.idvehicle = :id)
void deleteByVehicle(#Param("id") int idvehicle);
now you can just pass the id of the Vehicle like that:
deleteByVehicle(vehicle.getId());

How to create a serial numbers autogenerated in dynamoDb using annotations

I have created a pojo class in my java spring boot app and with respective annotations for doing create/update it's working fine but when i use the autogenerated key annotation it is creating some random id but i want those id column as serial numbers. Below i have given the annotations of my pojo class
#DynamoDBHashKey(attributeName = "id")
#DynamoDBAutoGeneratedKey
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
Generated random Id example
5d2af735-62ce-47d4-85bf-8beece056eb
How to generate the autogenerated column with serial numbers like we do in SQL autoincrement identity column?
No you cannot use DynamoDBAutoGeneratedKey to generate a incremented sequence,it is used to generate a random UUID.
The key generated in your case "5d2af735-62ce-47d4-85bf-8beece056eb" is standard UUID format which will help to scale and spread the data across the key space.
https://docs.oracle.com/javase/8/docs/api/java/util/UUID.html
If you want to generate a incremental sequence what you can do is create a SQL table "sequence_table", which will have only 1 column as "sequence_id" which is set to auto increment.
Whenever you want to insert data to Dynamo you can first insert in the SQL sequence table and get the latest id.Using this id you can create a new Dynamodb entry. If the annotation DynamoDBAutoGeneratedKey is not used , you can use your own custom key value.Whenever multiple process try to add a new sequence to the sequence_table, each process will first take a lock on the table and then it will insert a new id. So this solution will work in case of distributed system as well.
However on a side note if your business logic does not care about the sequence of id, you should go with UUID only as it is highly scalable , as it is not recommended to have an integer which increments by 1 to generate a hash key of the table. In order for the table to scale according to the provisioned capacity, requests should spread evenly across the shards.
As keys adjacent in a sequence will be stored in the same partition space.
Also as one might expect new users to be more active than very old users, and so we would be gearing load towards whichever partition serves the newest user rows.

OneToMany and ManyToOne mapping in spring boot

I need to create a group with multiple users (which are taken from user table) and single employee for every group in spring boot using rest api.
It means I want to perform OneToMany mapping between group to users and ManyToOne mapping between group and employee.
In fact 1 employee can handle more than one group, and all these data I want in a single table.

How to establish one to many relationship in Dynamo DB?

I have 2 different JSON Files. One with user details and other with order details. Order details table has a column user_id to match the user ordered for. I have to create a dynamo db table that has the order details nested inside the user details and insert the values from the Json files into this table using a spring-boot app. Can someone help me with this ? Do we have any example code ?
DynamoDB is NOT a relational DB so you can't have relations per se.
However, you have two ways (at least those come to my mind) to achieve what you want.
1) Have two tables: User and Order, the latter with userId field. When you load Order, get your userId and load also a User by the index id.
2) In your User.java you can have field List<Order> orders. Then you need to create Order.java and annotate this class with #DynamoDBDocument. This enables you to have custom objects in your #DynamoDBTable classes. Do not also forget about getters and setters since they are required.

How to use #SecondaryTable with CrudRepository?

I'm using SecondaryTable to map bean schema to multiple tables:
#Entity
#Table(name = "address1")
#SecondaryTables({
#SecondaryTable(name="address2")
})
How an I then tell spring to create a Repository that uses the values from table address2?
interface AddressRepository extends CrudRepository<Address, Long> {
//this one uses address1
}
I then want to be able to query only the secondary table by the CrudRepository. But how can I explicit tell spring to query the address2 table using the AddressRepository above?
(think of address2-table as a kind of archive table. Only if the address is not found in the primary address1-table, then address2 should be queried).
You can represent two tables which are store different but related data in one entity by using SecondaryTable like user and user_address tables. What You are trying is storing same data in two different tables whhich are identically same. Therefore, SecondaryTable doesn't fit your needs. You should use inheritance annotation with strategy table per class. Here is an example;
#Entity
#Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class AddressBase {
...
...
...
}
#Entity
#Table(name='address1')
public class Address1 extends AddressBase {}
#Entity
#Table(name='address2')
public class Address2 extends AddressBase {}
Then, you can write repository for each entity and do whatever you want.
I think you are misunderstanding what #SecondaryTable is for. It is a way to split a single entity among different database tables.
From the docs (http://docs.oracle.com/javaee/7/api/javax/persistence/SecondaryTable.html)
Specifies a secondary table for the annotated entity class. Specifying
one or more secondary tables indicates that the data for the entity
class is stored across multiple tables. If no SecondaryTable
annotation is specified, it is assumed that all persistent fields or
properties of the entity are mapped to the primary table. If no
primary key join columns are specified, the join columns are assumed
to reference the primary key columns of the primary table, and have
the same names and types as the referenced primary key columns of the
primary table.
Your annotations, in their current state, say that there exists an Address entity, with data in the address1 and address2 table, which can be combined by joining on the primary key of the address1 table.
I think for what you want to do, and have it work without overriding your CrudRepository, is to just use different tables. You will need to query both tables anyway if I am understanding you correctly.

Resources