How to create a serial numbers autogenerated in dynamoDb using annotations - spring-boot

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.

Related

How does jpa annotation sequenceGenerator works and how to avoid duplicate entries?

#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seqGen")
#SequenceGenerator(name = "seqGen", sequenceName = "seq", initialValue = 1)
private Long id;
Basically, i have three entities (fetched at the same times) that share the same sequenceName in my database.
I know for performance purpose, it's better to use the same tab for every entities with a SequenceGenerator.
When fetching a lot of datas, sometimes, i have a duplicate entries error, and basically changing the next_val of my sequence fix the problem temporarly.
I want to know how the SequenceGenerator work better and if there is a work around this issue ?
EDIT : could you explain me better what exactly is the purpose of a sequence and how his algorithm works ?
EDIT 2 : in a post, i saw this comment :
"Assume that you create a sequence object that has the CACHE option
enabled in Microsoft SQL Server 2012 or SQL Server 2014. When the
instance is under memory pressure, and multiple concurrent connections
request sequence values from the same sequence object, duplicate
sequence values may be generated. In addition, a unique or primary key
(PK) violation error occurs when the duplicate sequence value is
inserted into a table."
Is there a link with my current issue ?
There is no algorithm for sequence, it is +1 similar to autoincrement, also it has nothing to do with fetching your data that has duplicate entries.
Duplicate entries only mean that your database or code has a bad structure which leads to allowing data to be duplicated in the first place.
GenerationType. IDENTITY − In identity, the database is responsible to auto-generate the primary key. Insert a row without specifying a value for the ID and after inserting the row, ask the database for the last generated ID. Oracle 11g does not support an identity key generator. This feature is supported in Oracle 12c.
GenerationType. SEQUENCE − In sequence, we first ask the database for the next set of the sequence then we insert a row with return sequence id.
https://www.baeldung.com/hibernate-identifiers

Is there any way in Redis to put keys without any common regx pattern in the same hash slots?

I have the following data model for which I want to use redis as cache.
Employee: With a unique Employee_Id.
Department: With a unique Department_Id.
An employee can be part of only one department, a department can have many employees. Now, the operations the system should support are something like this.
Given a Employee_Id, find the department it is a part of.
Given a Department_Id, find the list of all it's employees.
Merge to departments, in this case employees of any one department will move to other, depending on the least no.of db operations.
I'm using DynamoDB as the persistent storage with two tables representing Employee and Department. I'm performing merge operations using dynamodb transactions, to ensure ACID.
Now, I'm planning to use redis as a cache between service and db. For each employee_Id as key, I'll store the department it is part of. For each department_id as key, I'll store the the list of members in the department. Now, for merge usecase I'll have to update the values for a no.of employee -> department mapping. For this I want to use redis transactions or operations like MSET, MGET etc.
For transactions in redis, we need to ensure that all keys are in the same hash slots. However, in our case EmployeeId(Key) are randomly generated UUID, they will not have any common regx. pattern to use for hash-tags. But, the values that they point to, i.e. Depatment_id will be common for them.
Is there any way in Redis to put keys(employee_Id) without any common regx pattern in same hash slots?
I'll put all such entries(for which I might want to perform transactions in future) in redis at the same time, hence I was thinking of appending a random string as hash-tag (between '{' and '}') to the keys but while getting value for the key, I'll not know the random the random string added, I need fetch values based on the original keys only.

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

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.

breeze.js insert parent/child with identity

Simple parent/child scenario like Order and OrderLineItems. I am inserting a new Order, the OrderID is an identity column (sql server). I'm also inserting OrderLineItems in the same SaveChanges transaction. I need to get the new OrderID into the OrderLineItems, but not sure how to do it. I have the appropriate FK relationships setup properly. When I save, I get an error that OrderID is a required field in OrderLineItems.
Will I have to split this out into 2 server calls? First to insert the Order, which will return the OrderID. And then another to insert the OrderLineItems?
The Breeze documentation discusses this topic (key generation) at several points including but not limited to: http://www.breezejs.com/documentation/save-changes, http://www.breezejs.com/documentation/extending-entities and http://www.breezejs.com/documentation/add-new-entity.
The basic idea idea is that providing that your model and metadata are set up properly, breeze can assign a temporary id in place of the identity column for use in linking your order and orderlineitem entities prior to being saved. As part of the save process, Breeze updates these temporary keys to their "real" key values and updates the local cache as well upon successful completion of the save.

How to stop a user from entering duplicate values

In one of my Java EE applications, I used a registration page to register new user and as soon as one registers, his/her registered values will be inserted into Oracle database. But there is no way of detecting duplicate values. So I thought about adding unique constraint to some column values. But later I learned, I can't declare more than one column as unique( In my case I already declared userid as primary key). But I need to make more than one column values unique (like emialid field). Again only adding unique can't help as if a user submits a form with duplicate value an exception will be caught and user won't be able to understand as he will be redirected to a blank page. So I have 2 questions.
1) How can I inform the user about inserting duplicate values?
and
2) How can I make more than one column unique in Oracle?
N.B. I don't know javascript!!
First, you certainly can declare multiple unique constraints on a table. You can declare that userid is a primary key and then declare emailid as unique. You can declare as many unique constraints as you'd like.
Second, your application would need to catch the duplicate key constraint and do something useful with it. Redirecting the user to a blank page would not be useful-- your application ought to catch the constraint exception and present a useful message to the user. For example, if you get an exception stating that the constraint UK_EMAILID was violated, you'd probably want to present an error message to the user saying something along the lines of "This email address already exists."
If you are using JPA, you can build a unique constraints :
#Entity
#Table(name = "entity_table_name", uniqueConstraints={
#UniqueConstraint(columnNames={"uniqueField1"}), // Unique value on one field.
#UniqueConstraint(columnNames={"uniqueField2", "uniqueField3"}) // Unique combination.
})
public class YourEntity {
private Long id;
private String uniqueField1;
private String uniqueField2;
private String uniqueField3;
private String uniqueField4;
// ...
}
The implementation (hibernate, eclipseLink) will take care of the oracle part.

Resources