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

Sunday 10 May 2020

Detect Malicious File in Java using Apache Tika

Dear Friends,

We often need to upload files in our web application/portal, and we start analyzing the risks associated with the activity.
I've been doing this over quite a certain period and realized this could be really fatal to our application, especially when you are working on a Production server in live internet.

After looking a lot over internet, Apache again came up as a savior with the API Apache Tika

At the time of writing this blog, the latest stable version  of Tika is

Maven Link

<!-- https://mvnrepository.com/artifact/org.apache.tika/tika-core -->
<dependency>
    <groupId>org.apache.tika</groupId>
    <artifactId>tika-core</artifactId>
    <version>1.24</version>
</dependency>

to get results, we merely need two lines
1. to initialize tika
2. to detect tika , any inputStream or File etc (attaching the screenshot)



ex:
Tika tika=new Tika();
System.out.println("File Detect : "+tika.detect(inputStream));

result:
File Detect : image/png
File Detect : application/x-msdownload now this file is malicious even though the hacker tried uploading the file using any valid extension.

Thank You :)


Monday 16 March 2020

MySQL Transnational Log

Dear User,

Today I'm sharing my learning to how to view the transactions logs that got generated while working with MySQL.

Steps
1. Goto
C:\ProgramData\MySQL\MySQL Server 8.0\Data

2. Open File based on your machine name like




Thank You :)

Sunday 8 March 2020

Tomcat Set Custom Common Error Page

Hi Fellas,

Today I'm sharing my learning to how to set custom common Error Page in Apache Tomcat.
Question: Why it is required ?
Answer: Minimal Answer ->Infosec Team.
Elaborate Anser -> When we do not set these pages, the default Error Page gives sensitive data like Server Version.
Steps do to it.
1. Remove all of the content of webapps other than your application.war/ear files.
2. Set the custom page.

Step 1.
Take a backup of all of the content of webapps.
BackUp of webapps
to keep in same directory

Doing this step will stop exposing the default applications.
Step 2.

This Step consists of two parts

Step A.
Open conf folder under tomcat root directory, and edit web.xml
Add these XML tags before the closing of <web-app>
i.e. in between
<web-app></web-app>

  <error-page>
        <error-code>404</error-code>
         <location>/error.jsp</location>
</error-page>
<error-page>
        <error-code>403</error-code>
         <location>/error.jsp</location>
</error-page>
<error-page>
         <error-code>500</error-code>
         <location>/error.jsp</location>
</error-page>


Step B.
Create a folder ROOT under webapps.
and create a error.jsp and restart the server.

Error Page Example.





Thank You :)

Monday 24 February 2020

Spring Error: The prefix "util" for element "util:list" is not bound.

Hi Friends,

Today I'm sharing my Spring learning to how to resolve the error

The prefix "util" for element "util:list" is not bound.

Open spring.xml and add the following lines in the beans tag

xmlns:util="http://www.springframework.org/schema/util"

http://www.springframework.org/schema/util 
http://www.springframework.org/schema/util/spring-util.xsd"

screenshot example:

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...