Showing posts with label Hibernate. Show all posts
Showing posts with label Hibernate. Show all posts

Tuesday 3 January 2023

Hibernate Level Two Caching.

Hi Folks, Today I'm sharing my learning on hibernate caching mechanism, cache is a wonderful concept for optimizing the application.
There are several vendors who enables the caching in a application. I'm using hibernate-cache.
Caching enables reuse.
It is directly associated with out hibernate life-cycle mostly in persistant state.
If we load any object in a session i.e. we fire a query to DB to get the object. This object is stored in default cache, the advantages of this cache are,
1. if we want to query the same object it will not hit the DB instead it will pick up the data from cache and avoid the DB communication.
2. if we change the value of any object even without using the save or update, and do a transaction, it will update the values.
There are two types of cache
Level-One (by default) In between same session
Level-Two (Need to enable)
In between multiple session, my below shared example is for level-two cache.
We need to two changes to perform
1. Changes in XML
2. Changes in Bean.
XML Changes

<property name="cache.use_second_level_cache">true</property>
        <property name="cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
        <property name="cache.ehcache.missing_cache_strategy">create</property>
Java Annotations

@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)

pom.xml


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.oracle</groupId>
    <artifactId>_012RevisionGetLoadFetchCascadeQuery</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.4.24.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-ehcache</artifactId>
            <version>5.4.24.Final</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.31</version>
        </dependency>
    </dependencies>
</project>

hibernate.cfg.xml

 


<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/practice</property>
        <property name="connection.user">root</property>
        <property name="connection.password">Welcome123#</property>
        <property name="show_sql">true</property>
        <property name="format_sql">true</property>
        <property name="hbm2ddl.auto">update</property>

        <property name="cache.use_second_level_cache">true</property>
        <property name="cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
        <property name="cache.ehcache.missing_cache_strategy">create</property>

        <mapping class="com.oracle.dto.BankAccount"/>
        <mapping class="com.oracle.dto.Citizen"/>



    </session-factory>
</hibernate-configuration>

BankAccount.java


package com.oracle.dto;

import lombok.AccessLevel;
import lombok.Data;
import lombok.Setter;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import javax.persistence.*;
import java.util.Date;

@Entity
@Data
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class BankAccount {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO,generator = "bid")
    @SequenceGenerator(name = "bid",sequenceName = "b_id",initialValue = 2000,allocationSize = 1)
    @Setter(AccessLevel.NONE)
    @Column(name="bank_id",updatable = false,nullable = false)
    private Long bId;
    private Integer branchCode;
    private Double accountBalance;
    @Temporal(TemporalType.DATE)
    @Column(name="account_opening_date",updatable = false,nullable = false)
    private Date accountOpeningDate;
}

Citizen.java


package com.oracle.dto;

import lombok.AccessLevel;
import lombok.Data;
import lombok.Setter;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import javax.persistence.*;
import java.util.Date;
import java.util.List;

@Entity
@Data
public class Citizen {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "cid")
    @SequenceGenerator(name = "cid", sequenceName = "c_id", initialValue = 1000, allocationSize = 1)
    @Setter(AccessLevel.NONE)
    @Column(name = "citizen_id", updatable = false, nullable = false)
    private Long cId;
    @Column(name = "first_name", nullable = false, updatable = true)
    private String firstName;
    @Column(name = "last_name", nullable = true, updatable = true)
    private String lastName;
    @Temporal(TemporalType.DATE)
    @Column(name = "joining_date", nullable = false, updatable = false)
    private Date joiningDate;
    @ManyToMany
    @JoinTable(name = "citizen_bank",
            joinColumns = {@JoinColumn(name = "citizen_id")},
            inverseJoinColumns = {@JoinColumn(name = "account_id")})
    private List accounts;
}

Main.java


package com.oracle.main;

import com.oracle.dto.BankAccount;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class CacheDriver {
    public static void main(String[] args) {
        SessionFactory sf=new Configuration().configure().buildSessionFactory();
        Session session1 = sf.openSession();
        BankAccount account1 = session1.get(BankAccount.class,2000l);
        System.out.println(account1);
        session1.close();
        Session session2 = sf.openSession();
        BankAccount account2 = session2.get(BankAccount.class,2000l);
        System.out.println(account2);
        session1.close();
        sf.close();
    }
}

Thursday 22 September 2022

java.lang.IllegalStateException: org.hibernate.TransientObjectException: object references an unsaved transient instance

 Hello All,

Today I'm sharing my learning experience, to solve the one issue while working with Springboot & Hibernate/JPA.

We often get the below error.


org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.oracle.dto.Asset
	at org.hibernate.engine.internal.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:347) ~[hibernate-core-5.6.10.Final.jar:5.6.10.Final]


The solution of this issue is to explicitly save the referred data.

I've solved this issue with the below code.


Transaction tx=session.beginTransaction();
        session.save(citizen);
        for (Asset asset:citizen.getAssetList()) {
            session.save(asset);
        }
        tx.commit();

Friday 16 September 2022

SpringBoot disable all default database related configuration.

 Hi Folks,

Today, I'm sharing my working experience to disable the default springboot database related configuration.

This can be achieved via two mechanism.

Mechanism 1: Annotations

@SpringBootApplication
@EnableAutoConfiguration(exclude = {
    DataSourceAutoConfiguration.class,
    DataSourceTransactionManagerAutoConfiguration.class,
    HibernateJpaAutoConfiguration.class})
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}


Mechanism 2 : application.properties.
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration

A Guide to Installing Oracle HR Schema on an Existing Docker Container

  Hi Reader, Today I want to share my learning on how to install Oracle HR schema on a existing docker container. Step 1: Download the verif...