ALU

hibernate

All Hibernate Annotations: Mapping Annotations

This article provides a quick overview of all Hibernate mapping annotations. These Hibernate mapping annotations are from the Hibernate official user guide.

Also, check out JPA Mapping Annotations

Check out Hibernate Developer Guide and Spring Hibernate Tutorials to develop J2EE enterprise applications.

Hibernate Mapping Annotations

@AccessType

The @AccessType annotation is deprecated. You should use either the JPA @Access or the Hibernate native @AttributeAccessor annotation.

Original Link

Hibernate Tips: How to Select Multiple Scalar Values in a Criteria Query

Hibernate Tips is a series of posts in which I describe a quick and easy solution for common Hibernate questions. Some of the most popular tips are also available as a book.

If you have a question for a future Hibernate Tips post, please leave a comment below.

Original Link

Hibernate 5: How to Persist LocalDateTime and Co With Hibernate

Do you use Java 8’s date and time API in your projects? Let’s be honest — working with java.util.Date is a pain and I would like to replace it with the new API in all of my projects.

The only problem is that JPA does not support it.

Original Link

Kotlin Data Classes With JPA

Introduction

In Kotlin, data classes are handy and provide default implementation for equals(),  hashCode()copy(), and  toString(). You get the implementation of these functions free of charge. For standard value classes, they are excellent, but you still need to understand what is going on particularly when using this feature within enterprise frameworks, such as Spring, sundry, and the widely-used Jakarta EE technologies, such JAX-RS or JPA. Because if you do not, you may get more or less than what you bargained for.

What Is a Data Class?

In a Kotlin data class, all properties that you declare in the primary constructor will be considered in the aforementioned functions.

Original Link

Hibernate Tips: How to Map Native Query Results to Entities

Hibernate Tips is a series of posts in which I describe a quick and easy solution for common Hibernate questions. Some of the most popular tips are also available as a book.

If you have a question for a future Hibernate Tip post, please leave a comment below.

Original Link

Top 5 Books to Learn Hibernate for Java Developers

Hibernate is one of the most popular, open-source ORM (Object Relational Mapping) frameworks, which has now become a standard for developing persistence layer on Java enterprise application, along with JPA (Java Persistence API). I often receive requests to suggest which book or training course is best to learn Hibernate or Spring and Hibernate.

This motivates me to write this article about some of the best books for learning Hibernate that are on the market. Earlier, I have shared info of the must-read books about the Spring framework for Java developers and some of the best Spring and hibernate training courses, which were quite helpful for picking a book and course on Spring.

Original Link

Using the Spring Data JPA

Spring Data JPA is not a JPA provider but a specification — it is a library/framework that adds an extra layer of abstraction on the top of our JPA provider. It simply “hides” the Java Persistence API and the JPA provider behind its repository abstraction.

JPA is the sun specification for persisting objects in the enterprise application. Therefore, it is used as a replacement for complex entity beans.

Original Link

Hibernate Mapping

Hibernate mappings are one of the key features of Hibernate. They establish the relationship between two database tables as attributes in your model. That allows you to easily navigate the associations in your model and Criteria queries.

You can establish either unidirectional or bidirectional i.e you can either model them as an attribute on only one of the associated entities or on both. It will not impact your database mapping tables, but it defines in which direction you can use the relationship in your model and Criteria queries.

Original Link

Object-Relational Mapping (ORM) With Redis Data Entities in Java

Object-relational mapping (ORM) techniques make it easier to work with relational data sources and can bridge your logical business model with your physical storage model. Follow this tutorial to integrate connectivity to Redis data into a Java-based ORM framework, Hibernate.

You can use Hibernate to map object-oriented domain models to a traditional relational database. The tutorial below shows how to use the CData JDBC Driver for Redis to generate an ORM of your Redis repository with Hibernate.

Original Link

Hibernate Query Language

In this tutorial, we will discuss the Hibernate Query Language. HQL is an object-oriented query language. Hibernate Query Language(HQL) is same as Structured Query language(SQL), except that in HQL, we use entity class name instead of table name.

HQL provides its own syntax and grammar.

Ex.  From Employee emp.

Where Employee is an entity class which is associated with employee table and emp is the alias name of Employee class.

It is an alternative to SQL query Select* from employee.

All hibernate queries are translated by hibernate into structured query for further processing. Hibernate also provides a way to use a structured query in hibernate. HQL syntax is not case sensitive, but class name and variable name are case sensitive.

Query Interface: It is n object-oriented representation of a Hibernate query. We can get Query instance by Session.createQuery(). 

This interface provides the various method:

  1. public int  executeUpdate() — Execute the update or delete statement.
  2. public String getNamedParameters() — It returns the names of all named parameters of the query.
  3. public String[] getQueryString() — Get the query string.
  4. public List list() —  It returns the query results as a List.
  5. public Query setMaxResults(int maxResults) — It is used to set the maximum number of rows to retrieve.
  6. public Object uniqueResult() — It is used to return a single instance that matches the query, or null if the query returns no results.

Let’s take a look at CRUD operations using HQL.

1. Select Query: Retrieve an employee detail where employee ID is 255.

Query query = session.createQuery("From Employee where employeeId= :id ");
query.setParameter("id", "255");
List list = query.list();
  1. Update Query: Update Employee name where ID is 255.
Query query = session.createQuery("Update Employee set employeeName =:eName" + " where employeeId= :id");
query.setParameter("employeeName ", "AKASH");
query.setParameter("id", "255");
int result = query.executeUpdate();

3.DELETE Query: Delete employee where ID is 255.

Query query = session.createQuery("Delete Employee where employeeName = :id");
query.setParameter(":id", "255");
int result = query.executeUpdate();
  1. Insert Query: In HQL, we can only insert values from another table.
Query query = session.createQuery("insert into Employee (employee_code, employee_name)" +"select employee_code, employee_name from employee_info");
int result = query.executeUpdate();

Note: The query.executeUpdate() will return how many number of record has been inserted, updated or deleted.

For More Information, see software application development.

Original Link

Spring Tips: JPA [Video]

Hi, Spring fans! In this installment, we look at the Java Persistence API (JPA) and its most ubiquitous implementation, Hibernate. We look at basic Spring support for JPA, Spring Boot’s auto-configuration and supported configuration properties, mapped superclasses, auditing (using Spring Data’s JPA auditing facility) and journaling (using the Hibernate Envers project and Spring Data Envers).

Speaker: Josh Long

Original Link

Hibernate Tips: How to Order the Elements of a Relationship

Hibernate Tips is a series of posts in which I describe a quick and easy solution for common Hibernate questions. Some of the most popular tips are also available as a book.

If you have a question for a future Hibernate Tip post, please leave a comment below.

Question:

How can I order the elements of an annotated relationship without writing my own query?

Get more videos from the Hibernate Tips playlist.

Solution:

JPA supports the @OrderBy annotation, which you can add to a relationship attribute as you can see in the following code snippet.

@ManyToMany
@JoinTable(name="BookAuthor",
joinColumns={@JoinColumn(name="bookId", referencedColumnName="id")},
inverseJoinColumns={@JoinColumn(name="authorId", referencedColumnName="id")})
@OrderBy(value = "lastName ASC")
private Set<Author> authors = new HashSet<Author>();

In this example, I want to order the authors who have written a specific book by their last name. You can do this by adding the @OrderBy annotation to the relationship and specifying the ORDER BY statement in its value attribute. In this case, I define an ascending order for the lastName attribute of the Author entity.
If you want to order by multiple attributes, you can provide them as a comma-separated list as you know it from SQL or JPQL queries.

Hibernate uses the value of the annotation to create an ORDER BY statement when it fetches the related entities from the database.

05:22:13,930 DEBUG [org.hibernate.SQL] – select authors0_.bookId as bookId1_2_0_, authors0_.authorId as authorId2_2_0_, author1_.id as id1_0_1_, author1_.firstName as firstNam2_0_1_, author1_.lastName as lastName3_0_1_, author1_.version as version4_0_1_ from BookAuthor authors0_ inner join Author author1_ on authors0_.authorId=author1_.id where authors0_.bookId=? order by author1_.lastName asc

Original Link

JPA and Hibernate: Persist LocalDate and LocalDateTime [Video]

Java 8 brought lots of great features, and one of the most important and most anticipated ones was the Date and Time API. There were lots of issues with the old API — I won’t get into any details on why we needed a new one. I’m sure you had to struggle often enough with it yourself.

All these issues were gone with Java 8. The new Date and Time API is well-designed, easy to use, and (finally) immutable. The only issue that remains is that you cannot use it with JPA.

Well, that’s not completely correct. You can use it, but JPA will map it to a BLOB instead of a DATE or TIMESTAMP. That means the database is not aware of the date object and cannot apply any optimization for it. That’s not the way we should or want to do it.

But that doesn’t mean that you can’t use the Date and Time API. You just have to decide how you want to add the support for it. You either use Hibernate 5, which provides proprietary support for the Date and Time API, or you take a few minutes to implement an AttributeConverter like I show you in this post.

Why Does JPA Not Support LocalDate and LocalDateTime?

The answer is simple, JPA 2.1 was released before Java 8 and the Date and Time API simply didn’t exist at that point in time. Therefore, the @Temporal annotation can only be applied to attributes of type java.util.Date and java.util.Calendar.

If you want to store a LocalDate attribute in a DATE column or a LocalDateTime in a TIMESTAMP column, you need to define the mapping to java.sql.Date or java.sql.Timestamp yourself. Thanks to the attribute converter, one of several new features in JPA 2.1, this can be achieved with just a few lines of code.

In the following video, I will show you how to create an attribute converter for LocalDateand LocalDateTime. If you want to learn more about attribute converter, have a look at How to implement a JPA 2.1 Attribute Converter or one of the other usage examples like a better way to persist enums or encrypting data.

The most important things you need to remember about attribute converter are also described in the free “New Features in JPA 2.1” cheat sheet.

Original Link

Hibernate Tips: How to Initialize Lazy Relationships Within a Query

Hibernate Tips is a series of posts in which I describe a quick and easy solution for common Hibernate questions. Some of the most popular tips are also available as a book.

If you have a question for a future Hibernate Tip post, please leave a comment below.

Get more videos from the Hibernate Tips playlist.

Question

How can I initialize a lazy relationship within a query to avoid LazyInitializationExceptions?

Solution

Hibernate throws a LazyInitializationExceptions if you try to use the attribute of a lazily fetched relationship outside of an active Hibernate Session.

EntityManager em = emf.createEntityManager();
em.getTransaction().begin(); Author a = em.createQuery("SELECT a FROM Author a WHERE id = 1", Author.class).getSingleResult(); em.getTransaction().commit();
em.close(); log.info(a.getFirstName() + " " + a.getLastName() + " wrote " + a.getBooks().size() + " books.");

You can avoid that by initializing the relationship before you close the session. Hibernate and JPA support different ways to do that. The easiest one is a JOIN FETCH statement within a query, like the one in the following code snippet.

EntityManager em = emf.createEntityManager();
em.getTransaction().begin(); Author a = em.createQuery("SELECT a FROM Author a JOIN FETCH a.books WHERE a.id = 1", Author.class).getSingleResult(); em.getTransaction().commit();
em.close(); log.info(a.getFirstName()+" "+a.getLastName()+" wrote "+a.getBooks().size()+" books.");

The additional FETCH keyword tells Hibernate to not only join the entity for the query but also to fetch it from the database to initialize the attribute. This prevents LazyInitializationExceptions if you access the relationship attribute outside of an active Hibernate Session.

If you liked this post, check out my book Hibernate Tips: More than 70 solutions to common Hibernate problems.

Original Link

Hibernate Show SQL

When you are developing Spring Boot applications with database interactions, you typically use Hibernate as the Object Relationship Mapping (ORM) tool.

Instead of directly coupling your code with Hibernate, often, you’d rather use Spring Data JPA, a Spring Framework project.

Spring Data JPA makes the implementation of the data access layer incredibly easy by abstracting most of the complexities involved in persisting data.

Often, when you are working with Hibernate and Spring Data JPA, you will need to see what is happening under the hood. It is very helpful to see the actual SQL statements being generated by Hibernate.

Due to the nature of the abstractions offered by Hibernate and Spring Data JPA, it’s very easy to inadvertently create n+1 queries — which is very detrimental to the performance of your application.

In this post, I’ll share a tip on how to configure Hibernate and Spring Data JPA to log executed SQL statements and used bind parameters.

The Application

For the purpose of this post, I’ve created a simple Spring Boot application. In this application, we can perform CRUD operations on a Product entity.

Here is the Product entity.

Product.java:

package guru.springframework.domain; import javax.persistence.*;
import java.math.BigDecimal; @Entity
public class Product { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; @Version private Integer version; private String productId; private String description; private String imageUrl; private BigDecimal price; public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public Integer getVersion() { return version; } public void setVersion(Integer version) { this.version = version; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getProductId() { return productId; } public void setProductId(String productId) { this.productId = productId; } public String getImageUrl() { return imageUrl; } public void setImageUrl(String imageUrl) { this.imageUrl = imageUrl; } public BigDecimal getPrice() { return price; } public void setPrice(BigDecimal price) { this.price = price; }
}

Below is a JUnit test class to save and retrieve products.

If you are new to JUnit, I’d suggest checking out my JUnit series of posts.

ProductRepositoryTest.java:

package guru.springframework.repositories; import guru.springframework.configuration.RepositoryConfiguration;
import guru.springframework.domain.Product;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import java.math.BigDecimal; import static org.junit.Assert.*; @RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {RepositoryConfiguration.class})
public class ProductRepositoryTest { private ProductRepository productRepository; @Autowired public void setProductRepository(ProductRepository productRepository) { this.productRepository = productRepository; } @Test public void testSaveProduct(){ //setup product Product product = new Product(); product.setDescription("Spring Framework Guru Shirt"); product.setPrice(new BigDecimal("18.95")); product.setProductId("1234"); //save product, verify has ID value after save assertNull(product.getId()); //null before save productRepository.save(product); assertNotNull(product.getId()); //not null after save //fetch from DB Product fetchedProduct = productRepository.findOne(product.getId()); //should not be null assertNotNull(fetchedProduct); //should equal assertEquals(product.getId(), fetchedProduct.getId()); assertEquals(product.getDescription(), fetchedProduct.getDescription()); //update description and save fetchedProduct.setDescription("New Description"); productRepository.save(fetchedProduct); //get from DB, should be updated Product fetchedUpdatedProduct = productRepository .findOne(fetchedProduct.getId()); assertEquals(fetchedProduct.getDescription(), fetchedUpdatedProduct.getDescription()); //verify count of products in DB long productCount = productRepository.count(); assertEquals(productCount, 1); //get all products, list should only have one Iterable<Product> products = productRepository.findAll(); int count = 0; for(Product p : products){ count++; } assertEquals(count, 1); }
}

Activating Logging in Hibernate

To activate the logging of the executed SQL statements with Spring Boot, set the log level of the org.hibernate.SQL category to DEBUG.

If you wish to see the bind values, you can set the log level of org.hibernate.type.descriptor.sql to TRACE.

If you are new to logging frameworks, refer my series on Log4J2.

Here is the logging configuration in the application.properties.

application.properties:

#show sql statement
logging.level.org.hibernate.SQL=debug #show sql values
logging.level.org.hibernate.type.descriptor.sql=trace

Here is the log output showing the SQL statements generated by Hibernate:

org.hibernate.SQL=debug 2018-02-04 22:34:46.861 DEBUG 1065 --- [ main] org.hibernate.SQL : select product0_.id as id1_0_0_, product0_.description as descript2_0_0_, product0_.image_url as image_ur3_0_0_, product0_.price as price4_0_0_, product0_.product_id as product_5_0_0_, product0_.version as version6_0_0_ from product product0_ where product0_.id=? org.hibernate.type.descriptor.sql=trace 2018-02-04 22:34:46.861 DEBUG 1065 --- [ main] org.hibernate.SQL : select product0_.id as id1_0_0_, product0_.description as descript2_0_0_, product0_.image_url as image_ur3_0_0_, product0_.price as price4_0_0_, product0_.product_id as product_5_0_0_, product0_.version as version6_0_0_ from product product0_ where product0_.id=?
2018-02-04 22:34:46.862 TRACE 1065 --- [ main] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [INTEGER] - [1]
2018-02-04 22:34:46.862 TRACE 1065 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([descript2_0_0_] : [VARCHAR]) - [New Description]
2018-02-04 22:34:46.863 TRACE 1065 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([image_ur3_0_0_] : [VARCHAR]) - [https://springframework.guru/wp-content/uploads/2015/04/spring_framework_guru_shirt-rf412049699c14ba5b68bb1c09182bfa2_8nax2_512.jpg]
2018-02-04 22:34:46.863 TRACE 1065 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([price4_0_0_] : [NUMERIC]) - [18.95]
2018-02-04 22:34:46.863 TRACE 1065 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([product_5_0_0_] : [VARCHAR]) - [1234]
2018-02-04 22:34:46.863 TRACE 1065 --- [ main] o.h.type.descriptor.sql.BasicExtractor : extracted value ([version6_0_0_] : [INTEGER]) - [1]

Activating Logging With Spring Data JPA

If you are using Spring Data JPA with Hibernate as the persistence provider, add the following two lines in application.properties:

spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

Here is the log output:

Hibernate: select product0_.id as id1_0_0_, product0_.description as descript2_0_0_, product0_.image_url as image_ur3_0_0_, product0_.price as price4_0_0_, product0_.product_id as product_5_0_0_, product0_.version as version6_0_0_ from product product0_ where product0_.id=?

Conclusion

As you can see, it’s very easy to enable the logging of SQL statements with Spring Boot and Hibernate.

Being able to see what Hibernate is actually doing with the database is very important.

Often, when I’m working on a Spring Boot project, I will enable the SQL output just as a sanity check. I may believe everything is okay. But I have, in fact, found problems which I was unaware of by examining the SQL output.

Original Link

Spring Boot + JPA + Hibernate + Oracle

In this tutorial, we will learn how to create a Spring Boot application that communicates with an Oracle data source through Hibernate.

Prerequisites

  • Eclipse IDE (neon release)
  • Maven 4
  • Java 1.8

Create a Maven Project

Open Eclipse, then create a new Maven project and name it SpringBootHibernate.

At the end of this tutorial, we’ll get the following project structure:

pom.xml

Configure Spring Boot inside your pom.xml by adding the following parent dependency:

<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.10.RELEASE</version>
</parent>

Then add a spring-boot-starter dependency in order to run the application as a standalone JAR application:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId>
</dependency>

Now in order to make use of Spring Data JPA and Hibernate, we need to just add spring-boot-starter-data-jpa as a dependency:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

As soon as we include Spring Boot Starter JPA in our project, we get the following features from a wide variety of dependencies:

  • Auto-configuration of an in-memory embedded database, which allows you to run your application without even setting up a database.
  • Auto-import of the JPA API and Hibernate. Adding this dependency will automatically import the JPA API and use Hibernate as the default implementation.
  • Auto-read of the data source and Hibernate configuration from application.properties.
  • Auto-creation of the entities as tables and auto execution of import.sql.

This is the whole pom.xml for reference:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.programmer.gate</groupId> <artifactId>SpringBootHibernate</artifactId> <packaging>jar</packaging> <version>0.0.1-SNAPSHOT</version> <name>SpringBootHibernate</name> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.10.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>

Add the Oracle Driver to the Classpath

In this tutorial, we’re going to override the default in-memory database provided by Spring Boot and use our own Oracle database.

For this purpose, we add “oracle-ojdbc6-11.2.0.3.jar” under WEB-INF/lib and define it in our classpath.

application.properties

Configure the Oracle data source and Hibernate in application.properties:

# create and drop tables and sequences, loads import.sql
spring.jpa.hibernate.ddl-auto=create-drop # Oracle settings
spring.datasource.url=jdbc:oracle:thin:@localhost:1522:orcl
spring.datasource.username=HIBERNATE_TEST
spring.datasource.password=HIBERNATE_TEST
spring.datasource.driver.class=oracle.jdbc.driver.OracleDriver # logging
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n
logging.level.org.hibernate.SQL=debug

Entities

Our entities represent a player and a team with a one-to-many relationship. Each team could have many players, whereas a player could only play with a single team at a time.

So we create our entities under the com.programmer.gate.model package:

Player.java:

package com.programmer.gate.model; import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator; @Entity
public class Player { @Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator = "player_Sequence") @SequenceGenerator(name = "player_Sequence", sequenceName = "PLAYER_SEQ") private Long id; @Column(name = "name") private String name; @Column(name = "num") private int num; @Column(name = "position") private String position; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "team_id", nullable = false) private Team team; public Player() { } // getters/setters
}

Team.java:

package com.programmer.gate.model; import java.util.List; import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator; @Entity
public class Team { @Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator = "team_Sequence") @SequenceGenerator(name = "team_Sequence", sequenceName = "TEAM_SEQ") private Long id; @Column(name = "name") private String name; @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "team") private List<Player> players; public Team() { } // getters/setters
}

Since we set spring.jpa.hibernate.ddl-auto=create-drop inside application.properties, our application will automatically create Player and Team entities in our database, along with their sequences and constraints.

Our application would also look for import.sql in the classpath and execute it, if found.

In our example, we define import.sql under src/main/resources in order to fill our tables with static data:

insert into Team (id,name) values(1,'Barcelona'); insert into Player (id, team_id, name, num, position) values(1,1,'Lionel Messi', 10, 'Forward');
insert into Player (id, team_id, name, num, position) values(2,1,'Andreas Inniesta', 8, 'Midfielder');
insert into Player (id, team_id, name, num, position) values(3,1,'Pique', 3, 'Defender');

Repositories

We define our repositories’ interfaces under com.programmer.gate.repository. Each repository extends Spring CrudRepository, which provides a default implementation for the basic find, save, and delete methods — so we don’t care about defining implementation classes for them.

PlayerRepository:

package com.programmer.gate.repository; import java.util.List; import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository; import com.programmer.gate.model.Player; @Repository
public interface PlayerRepository extends CrudRepository<Player, Long> { List<Player> findByTeamId(long teamId);
}

TeamRepository:

package com.programmer.gate.repository; import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository; import com.programmer.gate.model.Team; @Repository
public interface TeamRepository extends CrudRepository<Team, Long> { Team findByPlayers(long playerId);
}

Service

Now we define our service class, which holds the business logic of our application. Our service exposes two methods: getAllTeamPlayers() and addBarcelonaPlayer() ( just rename it to your favorite club if you don’t like Barcelona!). Our service layer communicates directly with the repository layer.

SoccerService.java:

package com.programmer.gate.service; import java.util.List; public interface SoccerService { public List<String> getAllTeamPlayers(long teamId); public void addBarcelonaPlayer(String name, String position, int number);
}

SoccerServiceImpl:

package com.programmer.gate.service; import java.util.ArrayList;
import java.util.List; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import com.programmer.gate.model.Player;
import com.programmer.gate.model.Team;
import com.programmer.gate.repository.PlayerRepository;
import com.programmer.gate.repository.TeamRepository; @Service
public class SoccerServiceImpl implements SoccerService { @Autowired private PlayerRepository playerRepository; @Autowired private TeamRepository teamRepository; public List<String> getAllTeamPlayers(long teamId) { List<String> result = new ArrayList<String>(); List<Player> players = playerRepository.findByTeamId(teamId); for (Player player : players) { result.add(player.getName()); } return result; } public void addBarcelonaPlayer(String name, String position, int number) { Team barcelona = teamRepository.findOne(1l); Player newPlayer = new Player(); newPlayer.setName(name); newPlayer.setPosition(position); newPlayer.setNum(number); newPlayer.setTeam(barcelona); playerRepository.save(newPlayer); }
}

Application.java

The final step is to create the Spring Boot initializer. This is the entry point of our application. We define Application.javaunder com.programmer.gate:

package com.programmer.gate; import java.util.List; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import com.programmer.gate.service.SoccerService; @SpringBootApplication
public class Application implements CommandLineRunner{ @Autowired SoccerService soccerService; public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Override public void run(String... arg0) throws Exception { soccerService.addBarcelonaPlayer("Xavi Hernandez", "Midfielder", 6); List<String> players = soccerService.getAllTeamPlayers(1); for(String player : players) { System.out.println("Introducing Barca player => " + player); } }
}

P.S.: It’s worth mentioning that the Spring Boot application automatically reads and creates entities, repositories, and services defined in the same package or in a sub-package relative to where you have your initializer class. So if we define Application.java under a different package, then we need to explicitly specify the package of the model, repository, and service.

Output:

When running the application as a standard Java app, we get the following output in the console:

2018-04-13 14:54:47 DEBUG org.hibernate.SQL - create sequence player_seq start with 1 increment by 1
2018-04-13 14:54:47 DEBUG org.hibernate.SQL - create sequence team_seq start with 1 increment by 1
2018-04-13 14:54:47 DEBUG org.hibernate.SQL - create table player (id number(19,0) not null, name varchar2(255 char), num number(10,0), position varchar2(255 char), team_id number(19,0) not null, primary key (id))
2018-04-13 14:54:47 DEBUG org.hibernate.SQL - create table team (id number(19,0) not null, name varchar2(255 char), primary key (id))
2018-04-13 14:54:47 DEBUG org.hibernate.SQL - alter table player add constraint FKdvd6ljes11r44igawmpm1mc5s foreign key (team_id) references team
2018-04-13 14:54:47 INFO o.h.tool.hbm2ddl.SchemaExport - HHH000476: Executing import script '/import.sql'
2018-04-13 14:54:47 INFO o.h.tool.hbm2ddl.SchemaExport - HHH000230: Schema export complete
2018-04-13 14:54:47 INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Initialized JPA EntityManagerFactory for persistence unit 'default'
2018-04-13 14:54:48 INFO o.s.j.e.a.AnnotationMBeanExporter - Registering beans for JMX exposure on startup
2018-04-13 14:54:48 DEBUG org.hibernate.SQL - select team0_.id as id1_1_0_, team0_.name as name2_1_0_, players1_.team_id as team_id5_0_1_, players1_.id as id1_0_1_, players1_.id as id1_0_2_, players1_.name as name2_0_2_, players1_.num as num3_0_2_, players1_.position as position4_0_2_, players1_.team_id as team_id5_0_2_ from team team0_, player players1_ where team0_.id=players1_.team_id(+) and team0_.id=?
2018-04-13 14:54:48 DEBUG org.hibernate.SQL - select player_seq.nextval from dual
2018-04-13 14:54:48 DEBUG org.hibernate.SQL - insert into player (name, num, position, team_id, id) values (?, ?, ?, ?, ?)
2018-04-13 14:54:48 INFO o.h.h.i.QueryTranslatorFactoryInitiator - HHH000397: Using ASTQueryTranslatorFactory
2018-04-13 14:54:48 DEBUG org.hibernate.SQL - select player0_.id as id1_0_, player0_.name as name2_0_, player0_.num as num3_0_, player0_.position as position4_0_, player0_.team_id as team_id5_0_ from player player0_, team team1_ where player0_.team_id=team1_.id(+) and team1_.id=? Introducing Barca player => Lionel Messi
Introducing Barca player => Andreas Inniesta
Introducing Barca player => Pique
Introducing Barca player => Xavi Hernandez 2018-04-13 14:54:49 INFO com.programmer.gate.Application - Started Application in 4.213 seconds (JVM running for 4.555)

Source code

You can download the source code from this repository: spring-boot-jpa-hibernate.

Original Link

Mocking JDBC Using a Set of SQL String/Result Pairs

In a previous post, I showed how the programmatic MockDataProvider can be used to mock the entire JDBC API through a single functional interface:

// context contains the SQL string and bind variables, etc.
MockDataProvider provider = context -> { // This defines the update counts, result sets, etc. // depending on the context above. return new MockResult[] { ... }
};

Writing the provider manually can be tedious in some cases, especially when a few static SQL strings need to be mocked and constant result sets would be OK. In that case, the MockFileDatabase is a convenient implementation that is based on a text file (or SQL string), which contains a set of SQL string/result pairs of the form:

Original Link

Hibernate Tips: How to Map a View With Hibernate

Hibernate Tips is a series of posts in which I describe a quick and easy solution for common Hibernate questions. Some of the most popular tips are also available as a book.

If you have a question for a future Hibernate Tip, please leave a comment below.

Get more videos in the Hibernate Tips playlist

Question:

How can I map a read-only database view with Hibernate?

Solution:

Database views, in general, are mapped in the same way as database tables. You just have to define an entity that maps the view with the specific name and one or more of its columns.

But the normal table mapping is not read-only, and you can use the entity to change its content.

Depending on the database you use and the definition of the view, you’re not allowed to perform an update on the view content. You should therefore also prevent Hibernate from updating it.

You can easily achieve this with the Hibernate-specific @Immutable annotation which I use in the following code snippet.

@Entity
@Immutable
public class BookView { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Version private int version; private String title; @Temporal(TemporalType.DATE) private Date publishingDate; private String authors; ... }

The @Immutable annotation tells Hibernate to ignore all changes on this entity, but you can use it in your queries to read data from your database.

List<BookView> bvs = em.createQuery("SELECT v FROM BookView v", BookView.class).getResultList();

If you like this post, check out my book Hibernate Tips: More than 70 solutions to common Hibernate problems.

Original Link

Marching Into Databases: What’s Been Happening?

It’s time for another Database Zone monthly round-up! Last time, we focused on database DevOps, looking into how to make DevOps work for your database solution, how to integrate DevOps into your workflow, and more. In this article, we’ll keep it simple and cover everything you need to know about databases from the past month, including the top database-related articles on DZone that you should check out, the top news that happened in the world of databases, DZone publications that dive deep into databases, and more. Let’s get started!


Databases on DZone

These are the top five articles from the Database Zone from the past month. Check them out so you’re up-to-date on the latest and greatest in database on DZone!

  1. Spring + Hibernate + EhCache Caching by Adam Zareba. Look at an example Spring Boot project to help you understand how to use Spring, Hibernate, and EhCache caching features.
  2. MySQL 8.0 vs. MariaDB: Comparison of Database Roles by Shree Nair. With the release of v8, MySQL has made great strides in closing the gap in user roles support that was already implemented in MariaDB.
  3. How to Use SQL Complete for T-SQL Code by Daniel Calbimonte. When looking for a tool to help me code faster and generate code automatically for a project with many stored procedures, I discovered SQL Complete. Here’s how to use it.
  4. The Types of Modern Databases by John Hammink. Where do you begin in choosing a database? We look at both NoSQL and RDBMSs to come up with a bird’s eye view of both ecosystems to get you started.
  5. Relational Data Model: Back to the Roots by Athanassios I. Hatzis, Ph.D. Athanassios makes the big claim that the R3DM/S3DM framework we propose to be adopted in DB management systems can be considered an extension to Codd’s relational model.

PS: Are you interested in contributing to DZone? It’s now easier than ever! Check out Bounty Board, where you can apply for specific writing prompts and win prizes!


Discovering Databases

Here, we’ll look at some of the news in the world of databases from the month of March. Read on for a look at

  1. A new data leak hits Aadhaar, India’s national ID database (ZDNet). This data leak affects potentially every member subscribed to the database — which is more than 1.1 billion Indian citizens.
  2. New Open Source Database to Track School Shootings (The Journal). Sad but true, school shootings are a very relevant topic in America these days. Learn about a new open source database being developed at John Jay College of Criminal Justice to track and analyze school shootings.
  3. Are configuration management database tools still relevant in 2018? (KnowTechie). It’s easy to believe that CMDBs have become an aging framework no longer needed in today’s agile computing world. But are they completely obsolete?

Dive Deeper Into Databases

  1. The DZone Guide to Databases: Speed, Scale, and Security. Advances in database technology have traditionally been lethargic. That trend has shifted recently with a need to store larger and more dynamic data. This DZone Guide is focused on how to prepare your database to run faster, scale with ease, and effectively secure your data.
  2. Data Warehousing: Best Practices for Collecting, Storing, and Delivering Decision-Support Data. This DZone Refcard walks you through each aspect of data warehousing. Gain a complete understanding of data modeling, infrastructure, relationships, attributes, and speedy history loading and recording with atomic data.

Original Link

Hibernate/GORM: Solving the N+1 Problem

Many developers who work with Hibernate or any other ORM framework eventually run into the so-called N+1 problem.

Our team faced it when we were working on a project using Grails. For its ORM, Grails uses a GORM “under the hood” that contains the same old Hibernate. In case you haven’t encountered this problem yet, let’s give you the gist of it. Let’s say we have the following perfectly typical scheme: “News – Comment(s)”.

WaveAccess_news-comment

There is a “News” item, and it can have several “Comments.”

If we need to get the last ten news items with their comments, based on the default settings, we will perform eleven database queries: one to get the news list and one for each news item in order to get its comments.

WaveAccess_Gorm_1

The ideal situation is one where the database is on the same machine, or at least the same local network, and the number of news items is limited to ten. But more likely, the database will be located on a dedicated server and there will be about 50 or so more news items on the page. This can lead to an issue with the server’s performance. Several solutions can be found to this problem using Hibernate. Let’s take a quick look at them.

FetchMode.JOIN

In the mapping for the association we’re interested in, or directly when executing the query, we can set up the JOIN fetch mode. In this case, the necessary association will be received by the same query. This will work for 1-1 or -1 connections, but for 1- queries, we will run into certain problems. Let’s take a look at the following query:

WaveAccess_Gorm_2

The first obvious problem is when limit 10 doesn’t work the way we need it to. Instead of returning the first ten news items, this query will return the first ten entries. The number of news items in these ten entries will depend on the number of comments. If the first news item has 10+ comments, it will be the only fetch result we get. All of this forces Hibernate to reject the database’s native methods for limiting and offsetting the fetch and process the results on the application server end.

The second problem is less obvious: if we don’t make it clear to Hibernate that we only want unique news items, then we’re going to get a list of doubled news items (one for each comment). In order to fix this, we need to insert the Result Transformer for the criterion:

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

Even if we get rid of all these drawbacks, this method still has more serious limitations: for example, it can’t cope with the task “also get the article’s author in addition to comments.”

FetchMode.SUBSELECT

Another potential alternative is SUBSELECT. Instead of doing a JOIN, it executes an additional query for linked entities while using the original query as SUBSELECT. In the end, we get only two queries rather than eleven: one base query and one query for each association.

WaveAccess_Gorm_3

This is a great option that will also work if we need to get both comments and authors at the same time. However, it also has some limitations.

First of all, it can only be used during the mapping-description phase by using the annotation @Fetch(FetchMode.SUBSELECT).

Second, we have no way of monitoring the use of this mode (unlike the same JOIN) at the moment the query is executed. We, therefore, have no way of knowing whether this mode is actually being used or not. If another developer changes the mapping, everything could fall apart. For example, the optimization might stop working and the original version with 11 queries could start being used again. If this happens, this connection will be incomprehensible to whoever made the change.

Third (and this is the deciding factor for us), this mode is not supported by a GORM-Grails framework for working with databases built on top of Hibernate.

Follow this link to learn more about possible fetch strategies.

Given all of these disadvantages, our only remaining option was to arm ourselves with an IDEA and lots of free time, and really dig around in the depths of Hibernate. The result was…

The Ultimate Solution

If we fantasize a little about the perfect solution, the following version suggests itself: make the fetch we need, then load the necessary collections all at once if necessary. It’d look something like this:

Query q = session.createQuery(“from News order by newDate“) q.setMaxResults(10) List news = q.list() BatchCollectionLoader.preloadCollections(session, news, “comments”)

Now let’s switch from fantasy to reality. The result of our inquiries was the following Groovy code (it can easily be rewritten in Java if necessary):

package cv.hibernate import groovy.transform.CompileStatic
import org.grails.datastore.gorm.GormEnhancer
import org.hibernate.HibernateException
import org.hibernate.MappingException
import org.hibernate.QueryException
import org.hibernate.engine.spi.LoadQueryInfluencers
import org.hibernate.engine.spi.SessionFactoryImplementor
import org.hibernate.engine.spi.SessionImplementor
import org.hibernate.loader.collection.BasicCollectionLoader
import org.hibernate.loader.collection.OneToManyLoader
import org.hibernate.persister.collection.QueryableCollection
import org.hibernate.persister.entity.EntityPersister
import org.hibernate.type.CollectionType
import org.hibernate.type.Type /** * Date: 08/03/2017 * Time: 15:52 */
@CompileStatic
class BatchCollectionLoader { protected static QueryableCollection getQueryableCollection( Class entityClass, String propertyName, SessionFactoryImplementor factory) throws HibernateException { String entityName = entityClass.name final EntityPersister entityPersister = factory.getEntityPersister(entityName) final Type type = entityPersister.getPropertyType(propertyName) if (!type.isCollectionType()) { throw new MappingException( "Property path [" + entityName + "." + propertyName + "] does not reference a collection" ) } final String role = ((CollectionType) type).getRole() try { return (QueryableCollection) factory.getCollectionPersister(role) } catch (ClassCastException cce) { throw new QueryException("collection role is not queryable: " + role, cce) } catch (Exception e) { throw new QueryException("collection role not found: " + role, e) } } private static void preloadCollectionsInternal(SessionImplementor session, Class entityClass, List entities, String collectionName) { def sf = session.factory def collectionPersister = getQueryableCollection(entityClass, collectionName, sf) def entityIds = new Serializable[entities.size()] int i = 0 for (def entity : entities) { if (entity != null) { entityIds[i++] = (Serializable) entity["id"] } } if (i != entities.size()) { entityIds = Arrays.copyOf(entityIds, i) } def loader = collectionPersister.isOneToMany() ? new OneToManyLoader(collectionPersister, entityIds.size(), sf, LoadQueryInfluencers.NONE) : new BasicCollectionLoader(collectionPersister, entityIds.size(), sf, LoadQueryInfluencers.NONE) loader.loadCollectionBatch(session, entityIds, collectionPersister.keyType) } private static Class getEntityClass(List entities) { for (def entity : entities) { if (entity != null) { return entity.getClass() } } return null } static void preloadCollections(List entities, String collectionName) { Class entityClass = getEntityClass(entities) if (entityClass == null) { return } GormEnhancer.findStaticApi(entityClass).withSession { SessionImplementor session -> preloadCollectionsInternal(session, entityClass, entities, collectionName) } } static void preloadCollections(SessionImplementor session, List entities, String collectionName) { Class entityClass = getEntityClass(entities) if (entityClass == null) { return } preloadCollectionsInternal(session, entityClass, entities, collectionName) }
}

This class contains two reloaded preloadCollections methods. The first one will only work for GORM (without a session), and the second one will work in both cases.

I hope this article is useful to you and will help you write great code!

P.S. Link to GIST.

Original Link

20 Books Java Programmers Should Read in 2018

Welcome to 2018, guys. If you are thinking of learning new things or want to improve your knowledge of essential Java technologies, then reading books can definitely help you. Today, I am going to share some of the best Java books from the last a couple of years that you can read in 2018 to learn Java and related technology better.

The list includes books to learn Java 8, Java 9, Spring 5, Groovy, Scala, Hibernate, Spring, Agile, Scrum, microservices, algorithms, and other important stuff for Java developers. You don’t need to read all of the books — this list will give you some ideas about interesting books on the things you want to learn — but if you are a nerd like me and have some time to read books, particularly during a commute, then this is quite an interesting list to follow. 

Here is my list of 20 books I read in 2017, and you can very well read them in 2018, too. Effective Java 3rd Edition should be the first one you read in 2018, but if you do get free time, you can use this list to pick up a book or two.

1. Java 8 in Action

This is one of my carry-forward books from 2016. I have been reading this regularly throughout 2017 while learning JDK 8 features. If you haven’t read it yet or have yet to start with JDK 8, 2018 is a good time to read this book. If you need tutorials on Java 8, you can also check out my list of my favorite Java 8 tutorials here.

best Java 8 books for programmers

2. Clean Architecture

This is one of the good books I discovered in 2017. I am a big fan of Uncle Bob’s writing, having read Clean Code and The Clean Coder already. These books talk more about getting your architecture right. It’s a one-of-a-kind book, and if you want to learn the pros and cons of different software architecture, this is the book to read.

best software architecture books for programmers

3. Grokking Algorithms

This is another great book I read in 2017 and probably the best book of 2017. Even though it’s very short in terms of its coverage of algorithms and data structures, what is covered is very entertaining and useful. It gives new life to old concepts by correlating with modern day examples, e.g. how Facebook might store its users. 

best Algorithm books for programmers

In short, it’s one of the must-read books for beginners who want to learn algorithms in 2018. And if you need more suggestions, check out my list of here

4. Building Microservices: Designing Fine-Grained Systems

Everyone is talking about microservices, but what are they? What is the main benefit of microservices architectures over monolithic ones? This book answers all of those questions. I have to yet to finish the book, so I am going to read it in 2018 as well.

best Microservices books for programmers

5. Soft Skills

One thing many programmers ignore is soft skills, e.g. email writing, focusing on career growth, and improving themselves. This is a great book from John Sonmez, and if you feel that you are stuck in your career or want to give it a boost in 2018, this is the book you should read.

best soft skill books for programmers

6. Database Design for Mere Mortals

One of the oldest, but best books on database design out there, I love to find a good, old book that is still relevant. If you are interested in learning database design or want to improve your database modeling, this provides a good starting point. If you need more recommendations, please see my full list of database design books here.

best database design books for programmers

7. Making Java Groovy

In 2017, I got a chance to work with Groovy a little bit, and this was the first book I read to learn it. If you decide to learn Groovy in 2018, this book provides a good foundation from a Java programmer’s perspective. It gives you just enough information to bring you up to speed without giving you unnecessary details that you might not understand at the start.

best Groovy books for Java programmers

8. Groovy in Action, Second Edition

This was the second book I read on Groovy in 2017. Even though Making Java Groovy is good to start with, it’s not comprehensive, and once you learn the basics of Groovy and write a couple of Groovy scripts, you need more detailed information. That’s where this book rocks. If you are learning Groovy in 2018, you can refer to this book.

Image title

9. TCP/IP Illustrated

This is one of the books I enjoyed least, but I still found it very useful. I have yet to finish with this one, but if you have to go deep into TCP/IP, this is the book to read.

best book to learn TCP/IP protocol

10. UML Distilled

In 2017, I had to write a couple of UML diagrams, and this is the book I read to refresh my knowledge about UML. If you decide to learn UML in 2018, you can check out this book, too.

best book to learn UML

11. Hibernate Tips

This is one of the most useful Java books from 2017 written by fellow blogger Thorben Janssen. This book provides 70 practical tips for Hibernate. If you use Hibernate, then these tips are good to fill your knowledge gaps. and if you decide to learn Hibernate in 2018, you can use this book to give your knowledge a new dimension.

Best book to learn Hibernate for experienced programmers

12. The Art of Agile Development

I have been using Agile for quite some time, but I still like to read books on Agile to refresh my knowledge and learn one or two new things. This one turned out to be a good book on Agile, and even regular users of Agile can learn a thing or two from this book.

Best book to learn Agile

13. Essential Scrum

I played the role of Scrum Master in 2017, and this was the book I read to get myself ready for the role. Scrum works great with small, onshore team, but it gets tricky when you need to manage a big team remotely, scattered around the world.

Best book to learn Scrum

This book provides all the tools and guidance you need to run Scrum meetings and how to become a Scrum Master. If you desire to become Scrum Master in 2018, this is the book you should read. 

14. Java Performance Companion

I have read a couple of Java performance tuning books in the past, e.g. The Definitive Guide to Java Performance, so I wasn’t expecting much. My only goal was to learn about G1 garbage collection, which I learned from this book. If your focus is on Java performance tuning in 2018, this book is a good starting point.

Best book to learn Java Performance Tuning

15. High-Performance Java Persistence

This was another leftover from 2016 that I finished in 2017. It’s another great book on Hibernate, focused on performance. If you are serious about improving your knowledge about Hibernate in 2018, I suggest you read both Hibernate Tips and this book.

Best book to learn Java Persistence

16. Functional Programming in Scala

I tried to get my hands dirty with Scala in 2017, but without much success. I read a book or two but didn’t do enough practice to really learn Scala. One reason for that was that I wasn’t using it on any of my projects, and there were more important things to focus on. Anyway, if you decide to focus on functional programming and Scala in 2018, you can check out this book. I might read it again in 2018 if time permits.

Best books to learn functional programming in Scala

17. Scala for the Impatient

This is one more book on Scala that I looked at in 2017. I am a big of Cay S. Horstmann’s writing, having read his books like Core Java Part I and II and Java SE 8 for the Really Impatient. This is a similar book that focuses on Scala. If you are learning Scala in 2018, this is the good book to start with.

Best books to learn Scala

18. Head First JavaScript

I have said this before, but JavaScript is the #1 programming language now, and if you don’t know JavaScript, you are missing a lot. Head First JavaScript is a must-read book for web development jobs and for learning frameworks like Angular, React, and jQuery. If you have yet to learn JavaScript, there is no better book than Head First JavaScript.

Best books to learn JavaScript

19. SQL CookBook

SQL is my favorite technology, and I am always looking for an interesting book on SQL. I found this one in 2017 and I am very happy to share it with you all as well. This is a very hands-on book on SQL that teaches you a lot of nice tips about using SQL in different databases. Read this book in 2018 if you want to improve your SQL skills. You can also use these websites to learn SQL queries to further improve your SQL knowledge.

Best books to learn SQL

20. The Complete Software Developer’s Career Guide

Last but not least, this is a great book for every software developer. If you are serious about your career and want to take control of it in 2018, this is the book you should read. John Sonmez of SimpleProgrammer.com explains a lot of practical stuff in this book and Soft skill which I shared earlier.

Best books to take care of career development

That’s all about the top 20 books I have read in 2017. I have read even more, but I am only listing these 20 for your reference.

Original Link

Spring + Hibernate + EhCache Caching

In this post, we are going to demonstrate the Spring cache + EhCache feature on an example Spring Boot project. Caching will be defined as data queried from a relational database (example configurations prepared for H2 and PostgreSQL database engines).

Application

Let’s consider the database layer and application layer.

Database Layer

The below diagram shows relationships between data tables. Our main object type is Company, which we will want to cache. Company is related to many other tables; some of the relationships are OneToMany, so querying the whole structure might be a time-consuming operation. 

Image title

Application Layer

The test application is developed in Spring Boot + Hibernate + Flyway with an exposed REST API. To demonstrate data company operations, the following endpoints were created:

@RestController
@RequestMapping("/company")
public class CompanyController { @Autowired private CompanyService companyService; @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseStatus(value = HttpStatus.OK) public @ResponseBody List<Company> getAll() { return companyService.getAll(); } @RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseStatus(value = HttpStatus.OK) public @ResponseBody Company get(@PathVariable Long id) { return companyService.get(id); } @RequestMapping(value = "/filter", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseStatus(value = HttpStatus.OK) public @ResponseBody Company get(@RequestParam String name) { return companyService.get(name); } @RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseStatus(value = HttpStatus.OK) public ResponseEntity<?> create(@RequestBody Company company) { companyService.create(company); HttpHeaders headers = new HttpHeaders(); ControllerLinkBuilder linkBuilder = linkTo(methodOn(CompanyController.class).get(company.getId())); headers.setLocation(linkBuilder.toUri()); return new ResponseEntity<>(headers, HttpStatus.CREATED); } @RequestMapping(method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseStatus(value = HttpStatus.OK) public void update(@RequestBody Company company) { companyService.update(company); } @RequestMapping(value = "/{id}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseStatus(value = HttpStatus.OK) public void delete(@PathVariable Long id) { companyService.delete(id); }
}

Cache Configuration

Let’s see how to enable caching and work with cache regions.

Enable Caching

To enable the annotation-driven cache management capability in your Spring application, we need to add @EnableCaching annotation to configuration class. This annotation registers CacheInterceptor or AnnotationCacheAspect, which will detect cache annotations like @Cacheable, @CachePut, and @CacheEvict.

Spring comes with the cache manager interface org.springframework.cache.CacheManager, so we need to provide concrete implementation for cache storage. There’re multiple implementations, such as:

  • Generic
  • JCache
  • EhCache 2.x
  • Hazelcast
  • Infinispan
  • Couchbase
  • Redis
  • Caffeine

In this post, we are going to use the EhCache provider. The below example shows cache enabling with EhCache-related beans in a separate configuration class. Overriding these two beans is not needed if you want to stay with the default definition, but we wanted to make cache transactions aware to synchronize put/evict operations with ongoing Spring-managed transactions.

@Configuration
@EnableCaching
public class CacheConfiguration { @Bean public EhCacheManagerFactoryBean ehCacheManagerFactory() { EhCacheManagerFactoryBean cacheManagerFactoryBean = new EhCacheManagerFactoryBean(); cacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache.xml")); cacheManagerFactoryBean.setShared(true); return cacheManagerFactoryBean; } @Bean public EhCacheCacheManager ehCacheCacheManager() { EhCacheCacheManager cacheManager = new EhCacheCacheManager(); cacheManager.setCacheManager(ehCacheManagerFactory().getObject()); cacheManager.setTransactionAware(true); return cacheManager; }
}

Cache Regions

Cached data could be stored in separate regions and we can define individual configurations for cache items with an XML file. Let’s define two regions:

  1. Storing companies by ID.
  2. Storing companies by name.

For both regions, the maximum elements kept in memory is 10,000 and the maximum time for the company before it’s invalidated is 60 minutes (for more detailed configuration, go to EhCache Official Reference).

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ehcache>
<ehcache> <diskStore path="java.io.tmpdir"/> <cache name="company.byId" maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="600" timeToLiveSeconds="3600" overflowToDisk="true"/> <cache name="company.byName" maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="600" timeToLiveSeconds="3600" overflowToDisk="true"/>
</ehcache>

Cache Operations

Let’s look at populating with @Cacheable, invaldating with @CacheEvict, and updating with @CachePut.

Populate: @Cacheable

The @Cacheable annotation indicates that the result of invoking a method (or all methods in a class) can be cached. Each time an advised method is invoked, the caching behavior will be applied, checking whether the method was already invoked for the given arguments.

In the example below, we want to cache Company objects in the company.byId cache region. The key in our region is the Company ID field. To handle something other than cache example test data (name starting with test), we can add a condition based on the result object (object returned as a result of a method).

@Cacheable(value = "company.byId", key = "#id", unless = "#result != null and #result.name.toUpperCase().startsWith('TEST')")
public Company find(Long id) { CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery<Company> query = builder.createQuery(Company.class); Root<Company> root = query.from(Company.class); root.fetch(Company_.cars, JoinType.LEFT); Fetch<Company, Department> departmentFetch = root.fetch(Company_.departments, JoinType.LEFT); Fetch<Department, Employee> employeeFetch = departmentFetch.fetch(Department_.employees, JoinType.LEFT); employeeFetch.fetch(Employee_.address, JoinType.LEFT); departmentFetch.fetch(Department_.offices, JoinType.LEFT); query.select(root).distinct(true); Predicate idPredicate = builder.equal(root.get(Company_.id), id); query.where(builder.and(idPredicate)); return DataAccessUtils.singleResult(entityManager.createQuery(query).getResultList());
}

To better see what’s happening, we can turn on debug-level logging for Hibernate:

logging.level.org.hibernate.SQL=debug

…and invoke REST company endpoint:

curl http://localhost:9000/company/1

Server logs will show the below SQL query only once:

2018-01-19 10:00:34.143 DEBUG 20256 --- [nio-8080-exec-4] org.hibernate.SQL : select distinct company0_.id as id1_2_0_, cars1_.id as id1_1_1_, department2_.id as id1_3_2_, employees3_.id as id1_4_3_, address4_.id as id1_0_4_, offices5_.id as id1_5_5_, company0_.name as name2_2_0_, cars1_.company_id as company_3_1_1_, cars1_.registration_number as registra2_1_1_, cars1_.company_id as company_3_1_0__, cars1_.id as id1_1_0__, department2_.company_id as company_3_3_2_, department2_.name as name2_3_2_, department2_.company_id as company_3_3_1__, department2_.id as id1_3_1__, employees3_.address_id as address_4_4_3_, employees3_.department_id as departme5_4_3_, employees3_.name as name2_4_3_, employees3_.surname as surname3_4_3_, employees3_.department_id as departme5_4_2__, employees3_.id as id1_4_2__, address4_.house_number as house_nu2_0_4_, address4_.street as street3_0_4_, address4_.zip_code as zip_code4_0_4_, offices5_.address_id as address_3_5_5_, offices5_.department_id as departme4_5_5_, offices5_.name as name2_5_5_, offices5_.department_id as departme4_5_3__, offices5_.id as id1_5_3__ from company company0_ left outer join car cars1_ on company0_.id=cars1_.company_id left outer join department department2_ on company0_.id=department2_.company_id left outer join employee employees3_ on department2_.id=employees3_.department_id left outer join address address4_ on employees3_.address_id=address4_.id left outer join office offices5_ on department2_.id=offices5_.department_id where company0_.id=1

The next time the repository method is invoked, data will be gathered from the cache.

The example below shows an implementation for caching data based on the name.

@Cacheable(value = "company.byName", key = "#name", unless = "#name != null and #name.toUpperCase().startsWith('TEST')")
public Company find(String name) { CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery<Company> query = builder.createQuery(Company.class); Root<Company> root = query.from(Company.class); root.fetch(Company_.cars, JoinType.LEFT); Fetch<Company, Department> departmentFetch = root.fetch(Company_.departments, JoinType.LEFT); Fetch<Department, Employee> employeeFetch = departmentFetch.fetch(Department_.employees, JoinType.LEFT); employeeFetch.fetch(Employee_.address, JoinType.LEFT); departmentFetch.fetch(Department_.offices, JoinType.LEFT); query.select(root).distinct(true); Predicate idPredicate = builder.equal(root.get(Company_.name), name); query.where(builder.and(idPredicate)); return DataAccessUtils.singleResult(entityManager.createQuery(query).getResultList());
}

Invalidate: @CacheEvict

The @CacheEvict annotation indicates that a method (or all methods on a class) triggers a cache evict operation, removing only specific or removing all items from the cache region.

Since the code below removes data from the database, the object needs to be removed from both caches:

@Caching(evict = {@CacheEvict(value = "company.byId", key = "#company.id"), @CacheEvict(value = "company.byName", key = "#company.name")})
public void delete(Company company) { entityManager.remove(company);
}

Update: @CachePut

With the @CachePut annotation, it’s possible to update the cache. In the below example, the cache for storing companies by ID is updated. It’s worth noting that since the company name is mutable, we cannot update the cache because we don’t know the old name value for that company. To proceed with that, we remove all entries in the cache for companies by name.

@Caching(evict = {@CacheEvict(value = "company.byName", allEntries = true)}, put = {@CachePut(value = "company.byId", key = "#result.id", unless = "#result != null and #result.name.toUpperCase().startsWith('TEST')")})
public Company update(Company company) { return entityManager.merge(company);
}

Cache Statistics

To preview live cache, statistics it is possible to expose EhCache MBeans through JMX like below:

@Configuration
@Dev
public class CacheMonitoring { @Autowired private EhCacheCacheManager ehCacheCacheManager; @Bean public MBeanServer mBeanServer() { MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer(); return mBeanServer; } @Bean public ManagementService managementService() { ManagementService managementService = new ManagementService(ehCacheCacheManager.getCacheManager(), mBeanServer(), true, true, true, true); managementService.init(); return managementService; }
}

The following MBeans will be exposed:

  • CacheManager
  • Cache
  • CacheConfiguration
  • CacheStatistics

Image title

Summary

In this post, we covered basic cache operations like getting, inserting, removing, and updating. Defining these operations and more complex requirements (like conditional caching or cache synchronization) is straightforward with annotations.

The source code for above listings can be found in the GitHub project company-structure-hibernate-cache.

Original Link

This Week in Spring: Kotlin, Hibernate, and Spring 5

Hi, Spring fans! Welcome to another installment of This Week in Spring! This week I am in Casablanca, Morocco for the amazing Devoxx Morocco event talking to developers in the hub of North Africa.

Can you believe it’s already the middle of November? And can you believe we are less than a month away from the amazing SpringOne Platform event in San Francisco, CA? I hope you’re going!

Now, without further ado, let’s get to it.

Original Link