JPA interview questions and answers

I remember the days when I would write SQL commands directly on ASP pages. Yeah, what a shame. Then with Java, I started using DAOs to isolate all that tedious and somewhat messy code to deal with databases. But those were the old days. Not so recently, ORM technologies gained a lot of traction, and persistence was made much easier. JPA, which is an ORM, removes so much hassle from programming persistence code that I consider it to be of great importance. That’s why I believe it is important to prepare yourself with some key JPA interview questions and answers for your next interview for a Java Developer Position.

Question: What is JPA?

About the question: This is such an important topic and such a basic question that I would consider it a very very bad sign if a candidate couldn’t answer this question at least at a basic level.

Answer: JPA stands for Java Persistence API. It is a specification on how Java should support the mapping between objects and relational databases for persistence, which is called ORM (Object Relational Mapping). It can be seen as a framework for persistence that is very lightweight and based on POJOs.

Several vendors provide implementations for the JPA. The candidate should be able to point a few, like Hibernate, Toplink, Eclipselink and Apache OpenJPA.

The Impedance Mismatch

A term that I like is “The Impedance Mismatch”, which I first came across in the excellent “Pro JPA 2”, from Mike Keith. It describes the difference between the relational and the object oriented models and the hard times one gets to try to bridge this gap. By the way, using these kinds of terms is positive in an interview ;-).

Please explain the concept of POJO Persistence in JPA?

About the question: This is a question that I would use to assess the candidate’s level of understanding about JPA in order to select my next questions.

Answer: Historically, many frameworks and tools used for persistence in Java required that classes would extend some abstract class or interface or would impose some other very intrusive requirement.

POJO Persistence is about being able to make any Plain Old Java Object persistent in a non-intrusive way. This is made possible in JPA because it adopts a metadata-driven approach. This metadata can be very easily set using annotations in your POJOS or can be set externally using XML.

What is the EntityManager in JPA?

Answer: JPA is said to be “non-intrusive” but not “transparent persistence”. This means the entities don’t persist themselves magically. There is a need for an API which provides operations to persist and retrieve objects from the database. This is the reason of the EntityManager to exist, its “râison-dêtre”. EntityManager is the main API to provide methods to persist or retrieve data, methods such as persist or find.

The way to obtain an instance of the EntityManager is through an EntityManagerFactory or have it injected for you if you are using the Enterprise Edition.

Check these links to learn more:

Take a look at our question about Persistent Context as well.

What is a Persistent Context in JPA

Answer: Persistent objects are the ones being managed by the EntityManager. The Persistent Context is a set of entity instances being managed by the EntityManager. The identity is used to determine the uniqueness within the set because only one instance of an entity can exist within a Persistent context.

Check these links to learn more:

Could you please explain the concept of Entity in the context of JPA?

Answer: In the context of the Java Persistence API, an Entity means a POJO which has a state, can have relationships and would have its persistence to a relational database managed by some implementation of the JPA.

An Entity is an object that is persistable, it also must have a persistence identity, which means it has a primary key and a row of its own in a database table. There must be a mapping between a database table and the class, which can make extensive use of defaults to required the minimum necessary configuration.
The class can either be annotated with the @Entity annotation or be mapped in an external XML file. Another required annotation (or configuration in XML) is @Id, which marks the field or property (either the field itself or the getter method) responsible for holding the persistence identity (primary key).

Configuration by exception

This is a term you can use to refer to the fact that JPA makes extensive use of defaults, so one needs only to configure what is out of ordinary, or, in other words, configure by exception.

What is a Persistence Unit in JPA?

Answer: Persistence Unit is the configuration settings of a logical grouping of user defined persistable classes that an EntityManager is supposed to manage.

It is in a file called persistence.xml that we can describe the persistence unit. One single file can contain one or more persistence units. The persistence unit is named to create an EntityFactory. We are required to provide the Persistence Unit name in order for that configuration to be used.

More information:

What is the JPQL?

Answer: JPQL stands for Java Persistence Query Language. It is a very powerful query language, similar to SQL, to execute queries across entities and their relationships instead of directly against the data model.

You might be asking yourself why in the world would you need a Query Language given you could be writing SQL directly?
The answer is that it has two major advantages over writing SQL directly: The first one is that JPQL has an object-oriented syntax. The second one, which is kind of a consequence from the first is that JPQL is also not bound to a database schema, it uses a schema abstraction based on the object model instead of the relational one.

This code assumes you have an instance of EntityManager in the variable entityManager. Than it creates a query instance and asks for the result:

TypedQuery<Person> query = entityManager.createQuery(“SELECT p FROM Person p”, Person.class);

List<Person> people = query.getResultList();

The JPQL presents some features (not exclusive):

  • It can produce Single or Multiple value result types
  • It has aggregate functions, sorting and grouping clauses
  • Support for join, both inner and outer
  • Update and delete

What is a named query in the JPA? How to set and execute it?

Answer: In the context of JPQL, Named queries are a way to organize query definitions associating them with names. It is important to have in mind that the names must be unique within a single Persistent Unit.

There are two ways to set Named queries, either using annotation or setting them in external files.

The easiest way to set them is by using the @NamedQuery annotation in the class definition of any Entity. The only drawback is that it somehow “pollutes” the class with the queries.

@NamedQuery(name=”School.findByName”,  query=”SELECT s FROM School s WHERE s.name = :schoolName”)

The other option, the use of external file. Example (I’ve removed a lot of XML details to make the main construct clearer):

<?xml version=”1.0″ encoding=”UTF-8″?>

<entity-mappings …>

 <named-query name=”School.findByName”>

   <query>SELECT s FROM School s WHERE s.name = :schoolName</query>

 </named-query>

</entity-mappings>

And in the persistence.xml, using the “mapping-file” tag, the above file can be referenced.

To add several named queries is pretty straightforward in the external file, just add as many “named-query” tags as necessary. When using annotations, though, it is still very easy but you need to remember that the @NamedQuery annotation has to be nested within the @NamedQueries annotation:

@NamedQueries({

@NamedQuery(name=”…”,  query=”…”),

@NamedQuery(name=”…”,  query=”…”),

@NamedQuery(name=”…”,  query=”…”)

})

The last point the candidate should mention is how to execute the named query. It is necessary to invoke the instance method createNamedQuery from the EntityManager:

em.createNamedQuery(“School.findByName”, School.class).setParameter(“name”, name).getSingleResult();

if the query is expected to return more than one value, use the method .getResultList() instead of the .getSingleResult()

Some examples used were adapted from this post (in Portuguese) about named queries in external files.

What is paging and how to achieve it in JPA?

Answer: A common problem with large result sets is that they can be inefficient to display and or to load. The applications must be able to cope with this problem and a common technique is to present the data in fixed size batches called pages, the paging also provides a way to navigate the results, retrieving other pages.

Pagination is made very easy with JPA, the two interfaces related to queries, Query and TypedQuery have the methods setFirstResult() to set what is the first element of the given page and setMaxResults() to determine the page or size.

What happens if a query is executed against entities that have uncommitted changes?

Answer: One might be tempted to think that the changes that are not yet committed would not visible to the queries. This possible explanation could stem from the fact that queries are executed directly against the database, not using the internal cache.

However, the persistence provider ensures, by default, that queries can see pending transactional changes in their resultset. To have more control, both EntityManager and Query interfaces provide a way to set the flush mode, which is used by the provider to determine how to handle pending changes and queries.

The options available are AUTO (default option) and COMMIT. The first tells the provider that the pending changes should be included in the results. The second option allows the provider to just ignore uncommitted changes.

What is the Java Criteria API?

Answer:Retrieving entities is one of the most important functions of an ORM technology. For that, JPA offers two different ways to express queries, the query languages (JPQL and native SQL) and the Criteria API.

This API, part of the JPA, allows the creation of dynamic queries. One of its advantages over JPQL is that it can be validated at compile time, so problems can be discovered much earlier.

Please explain the Life cycle of an Entity within JPA

Answer: Remember an Object is considered Managed if it is associated with an Entity Manager. So, once you create an object it is considered transient (not managed by an Entity Manager and no representation in the database). If this object is persisted, it becomes managed.

There are other ways to get to a managed state, like when you retrieve objects from the database, such as using find, or when you have a detached (we are going to see this one soon) that you merge.

Detached: These are objects that are not managed by the EntityManager, but they are persisted. In other words, they have are stored in the database. These objects can return to a MANAGED state if it is merged back. The EntityManager’s merge method is invoked with the object as a parameter.

What is lazy loading in JPA?

Answer: Performance is a very important topic when loading the relationships of an Entity. Lazy loading represents a mechanism used by many ORMs, such as JPA for Java or Entity Framework for .Net to load information just when they are actually demanded.

Although the objective of Lazy Loading is to improve performance, the wrong use of Lazy or Eager strategies can significantly be detrimental to it.

The strategies JPA uses by default are almost always the best choice. Unfortunately, this is not always the case. So one should know what are the defaults and its weakness.

Lazy strategy, on the other hand, is used by default with relationships of the types one-to-many or many-to-many. This means that the relationships will not be loaded immediately with the entity, it will wait for an accessor method to be invoked, such as a getter. Once the method is invoked, it executes a query against the database to finally load the data.

Look for the code below, where School has many students, in a one-to-many relationship, therefore using Lazy Loading by default. There is a performance problem with this code:

for(School school : schools) {

for(Student student : school.getStudents(){

System.out.println(student.getID());

}

}

It will be executed in what is known as N+1 queries, which is a known problem in the using JPA. In this particular case, having an Eager strategy could have had better performance.

What are Embeddable classes? How to create them?

Answer: An Embeddable class represents part of an Entity persistent data but it does not contain a persistent identity of their own.  Instances of an embeddable class share the identity of the entity that owns it.

@Entity
public class Order {

@Id
protected long id
@Embedded
Payment payment;

}

@Embeddable
public class Payment {

private String type;
private String currency;
private double amount;

// … }

<entity-mappings>

<entity class=”techcareersource.jpa.Order”>

<attributes>

          


</attributes>

</entity>

</entity-mappings>

As we can see in the examples above, embedded objects can be either specified in XML using the embedded element or it can be annotated as @Embeddable and @Embedded annotations.

Check the Oracle tutorial page about Embeddable Classes.

What are Persistent Fields?

Answer: Simply put, ORM is about mapping objects to relational databases.

In the case of JPA, it does not even require that the object being mapped follow the JavaBeans convention. The fields, except public ones, can be directly mapped to a column in a table in the database.

For field access to be used, it is just a matter of annotating the one single field of the entity for JPA to use field access. The other fields become persistent by default, which means they too get mapped to columns of the same table as the Entity. If a field should not be persistent, one must either annotate it with @Transient or simply use the Java transient modifier.

What are Persistent Properties?

Answer: We’ve answered what were Persistent Fields.

Persistent properties are the mapping between setter/getter from an Object that follows the JavaBean conventions to columns on a table in a relational database.

It is required that the annotations be applied to the getter methods. The same rules about the @Transient annotation or transient modifier apply here.

Please, briefly explain Multiplicity in Entity Relationships and what are its possible types?

Answer: Entities have relationships with other entities, and a good ORM has to be possible to map these relationships to the database.

There are two important concepts related to Entity Relationships, namely Role, and Cardinality. A student has a relationship with a school, he or she plays the role of studying in that School. The cardinality refers to a number of entities exist on each side of a relationship. Let’s say that ordinarily, a student has one school, but a school has many students.

It is the cardinality of both source and target roles that are used to name the mappings.

We have, so, four types of multiplicities, that we can divide into two groups.

Single-Valued Associations

When the target role has a cardinality of one, it is about single-valued associations.

  • One-to-one:
    The cardinality on both sides of the relationship is one. This would be the case for a School with a Principal, where the School has only one person playing the role of Principal, and this person plays this role for a single School.
    In the School entity, there would be a field or property to store a Principal. The Principal probably also have a School entity field or property.
    The easiest way to signal this association is by using the @OneToOne annotation on the persistent field or property.
  • Many-to-one:
    The cardinality on the source side is many and on the target side of the relationship is one. From the perspective of a Student, the relationship with School is many to one.
    The easiest way to signal this association is by using the @ManyToOne annotation on the persistent field or property.

Collection-Valued Associations

When the source role has a cardinality of one, it is about collection-valued associations.

  • One-to-many:
    This is the case of source role having a cardinality of one and target source of many. Still, in the example of School, it has many Students or many ClassRooms.
    The easiest way to signal this association is by using the @OneToMany annotation on the persistent field or property.
  • Many-to-many:
    This is the case where both source and target roles having a cardinality of many. An example would be that each Teacher has many Students, and each Student has many Teachers.
    The easiest way to signal this association is by using the @ManyToMany annotation on the persistent field or property.

Check the Multiplicity in Entity Relationships from Oracle.

What is the difference between “@JoinColumn” and “mappedBy” Foreign Key Constraints

Imagine a relationship of one to many, like a School which has many Students.

The most common way to represent this in the database would be to use a foreign key like “schoolID” in the Students table.

If we follow this, then we would have:

@Entity

public class School {

@OneToMany(mappedBy = “student”)

private List<Student> departments;

}

@Entity

public class Student {

@ManyToOne

@JoinColumn(name = “schoolID”)

private School school;

}

The side of the relationship (considering the data scheme) that has the foreign key or the “join column”, is considered as “owner” of the relationship. It is important to understand this because the annotations are always defined on the owning side of the relationship. In our example, the Student owns the relationship, so it is in this class that the annotation @JoinColumn must be defined.

The mappedBy, on the other hand, is used in the non-owning or inverse side of the relationship.

Please explain what are Compound Primary Keys.

It is not always possible or desirable to have a single field to represent the identity of an entity. The primary key is composed of more than a single field. In the database, it means the Primary Key is composed of more than a single column.

To represent a compound primary key in an Entity it is necessary to have a separate class, called Primary Key Classes, containing the primary key fields. These classes must define the methods equals() and hashCode().

An example of the compound key might be from a Course entity, where it can be formed from the topic and the level, as CIVIL_LAW-101 and CRIMINAL_LAW-101.

What are the differences between EntityManager.merge() and EntityManager.persist()?

Answer: The merge method can both update and existing entity and insert a new one, while the persist method only inserts an entity.

The question that arises is why would one choose to use the persist method, given that merge apparently can do both saving and updating.

The main difference is in the treatment your Entity will receive after the methods are invoked.

The persist method will insert your entity and make the entity instance itself managed, while merge will either insert or update your Entity, but it makes a copy of your instance and that copy becomes managed.

The picture below should help understand what happens:

differences between EntityManager.merge() and EntityManager.persist()

Differences between EntityManager.merge() and EntityManager.persist()

There is a very good discussion about this topic on stackoverflow.

When to override “equals() & hashcode()” method in an Entity class ?

Whenever you need to have Entity objects within collections such as Set, List etc the identity of objects become an issue because once an object is in the collection, the behavior of changing its identity is probably not what you want.

Entities that represent the same Entity should be considered equal and return, therefore, the same hashcode. The most straightforward implementation would be to just use the id in the implementations of both equals() and hashcode(). The problem with this approach is that it would change identity once the object is persisted, after all, Entities in general just receive their ids upon insertion. If you implement an equals method that does something while id is null and something else after it is set, which would be a possible first solution that comes to mind, the identity of this Entity would change once it receives an id.

Like we said, identity change is very problematic for instances in collections. Hashcode should always return the same value for the same identity and collections make use of the hashes to store the items internally.

Let’s look at an example in code:

Set<School> schools = new HashSet<>();

School s = new School();

schools.add(s);

schools.contains(s); //returns true. Same hash as when inserted in set, right?

s.setID(5); //this would happen if it had been persisted

schools.contains(s); //returns false. Different hash now.

So it is fundamental that the implementation of equals() and hashCode() is valid both before and after the object is persisted.

The natural answer is to have an id generated as soon as the entity first created.

Check these references:

Explain Directionality in JPA Relationships?

Entities can have relationships with other entities. For this to happen, at least one side of the relationship must have an attribute that refers to the other entity.

If only one side knows about the relationship, then the relationship has only one direction, it is called unidirectional.

If on the other hand, both sides of the relationships have attributes pointing to each other, this relationship is called a bi-directional. In the end, a Bidirectional relationship is nothing more than a pair of unidirectional relationships.

The relationship between Student and Locker - JPA interview questions and answers

The relationship between Student and Locker

The relationship between Student and Locker can be modeled as a bi-directional one-on-one relationship.

A bi-directional role has to follow some rules (check them all at here at the Oracle’s tutorial page). The most important one to remember is that the owned side of the relationship must use the “mappedBy” element to point to the owning side (the one which contains the foreign key). Check our “What is the difference between @JoinColumn and mappedBy Foreign Key Constraints” .

What are the different types of cascade Operations for Entities?

The following are the different types of cascade operations available for Entities:

  • CascadeType.PERSIST – Triggered when the method persist from EntityManager is invoked and an Entity is persisted; The related entity will be persisted as well.
  • CascadeType.DETACH – Triggered when an entity is removed from Persistence Context. The related entity will be detached as well.
  • CascadeType.MERGE – Triggered when a change is made to an Entity, either when the transaction in which the change happened ends or when the merge() method is invoked. The related entity will be merged as well.
  • CascadeType.REFRESH – Triggered when an entity is making up-to-date by receiving information from the database; The related entity will be refreshed as well.
  • CascadeType.REMOVE – Triggered when an entity is removed from the database. The marked relationships will be removed as well.
  • CascadeType.ALL – All prior triggers will be reflected on the related entities.

More details on https://docs.oracle.com/cd/E19798-01/821-1841/bnbqm/index.html

Leonardo Campos
 

Hi, besides writing about Java, I’m one of the guys behind this website alongside with Anselmo.
I’ve being working with IT for the last, let’s say, 17 years. About 10 of them as a Software Developer. The last 7 years my role has been a bit more managerial. I have being involved with Technical Interviews for quite a while now and have helped the hiring of pretty awesome developers.

Click Here to Leave a Comment Below 0 comments