Hibernate
Hibernate uses PreparedStatement exclusively, so not only it protect against SQL injection, but the data access layer can better take advantage of server-side and client-side statement caching as well.
π‘ When you open a transaction => you have a Persistence context, where retrieved entities are kept (entities manipulated by EntityManager). When transaction is closed => persistence context is also closed. Session = Persistence context.
Write-behind cache
The Persistence Context acts as a transactional write-behind cache, deferring entity state flushing up until the last possible moment.

Because every modifying DML statement requires locking (to prevent dirty writes), the write behind cache can reduce the database lock acquisition interval, therefore increasing concurrency.
But caches introduce consistency challenges, and the Persistence Context requires a flush prior to executing any JPQL or native SQL query (as otherwise it might break the read- your-own-write consistency guarantee).
Session flush()
session in-memory state -> database
Happens automatically for cases:
before query execution
when transaction is committed
JPA entity state

The Persistence Context captures entity state changes, and, during flushing, it translates them to SQL statements. The JPA EntityManager and the Hibernate Session (which includes additional methods for moving an entity from one state to the other) interfaces are gateways towards the underlying Persistence Context, and they define all the entity state transition operations.

Hibernate entity state

Relationship
One to one
Which table has a foreign key => this table owning a relation
It will result in following DB structure: Student: | id | name | passport_id | <= β οΈ owing a relationship Passport: | id | number |
βΉοΈ @OneToOne relationship fetch is always eager (fulfilled entity is returned, with opposite entity)
Lazy fetch
Bidirectional relation
It will result in following DB structure: Student: | id | name | passport_id | Passport: | id | number | student_id | π« This is bad because of data duplication.
π It will result in following DB structure: Student: | id | name | passport_id | Passport: | id | number |
Many to one
It will result in following DB structure: Course : | id | name | Review: | id | rating | course_id |
Many to many
Inheritance
Single table

it is good that it is single table (better for performance!!)
it is bad that there are many nullable columns
Table per class

many tables may be created because of many subclasses
Not a good choice (c)
Joined

fields from super class are stored into EMPLOYEE table
subclass columns are stored in separate tables
db design is clear
performance may be poor in fetching all kinds of employees (many joins will happen)
Better for data integrity
Mapped super class
JPQL
Criteria queries
Transactions
Atomicity, Concurrency, Isolation, Durability
Dirty Read
Non Repeatable Read
Phantom Read
Read Uncommited
possible
possible
possible
Read Commited
(lock on specific value in row)
SOLVED
possible
possible
Repeatable Read
(whole row is locked)
SOLVED
SOLVED
possible
Serializable
(any row matching constraint is locked)
SOLVED
SOLVED
SOLVED
Spring Transactional
is logically equal to
Redundant save() invocation
When a method is transactional, then entities retrieved within this transaction are in the managed state, which means that all changes made to them will be populated to the database automatically at the end of the transaction. Therefore either the save() call is redundant
Ignored Transactional annotation
For Spring in order to take an action on transactions two expected criteria:
The method visibility canβt be any other than public.
The invocation must come from outside of the bean.
This is due to how Spring proxying work by default (using CGLIB proxies).
When you auto-wire a bean of type Sample, Spring in fact doesnβt provide you exactly with an instance of Sample. Instead, it injects a generated proxy class that extends Sample (yes, thatβs the reason why you canβt make your spring bean classes final) and overrides its public methods to be able to add extra behaviour (like transactional support).
Solution 1
Extract the method to another class and make it public.
Solution 2
Use AspectJ weaving instead of default proxy-based Spring AOP. AspectJ is capable of working with both: non-public methods and self-invocations.
Solution 3 (only for self-invocation)
Disclaimer: I wouldnβt use this βsolutionβ in the production code.
Rollbacks
The rule when transaction rollbacks are triggered automatically is very simple but worth reminding: by default, a transaction will be rolled back if any unchecked exception is thrown within it, whereas checked exceptions donβt trigger rollbacks.
We can customize this behaviour with parameters:
noRollbackFor - to specify runtime exception, which shouldnβt cause a rollback
rollbackFor - to indicate which checked exception should trigger rollbacks
Last updated
Was this helpful?