Skip to main content

Spring Data JPA One-To-Many Explained Simply

 One-to-many relationships are used when a single entity is associated with many other entities.

For example, a Blog can have many associated Posts, BUT each Post is only associated with one Blog.

This simply means you map child entities (Posts) as a collection in the parent object (Blogs).

Spring Data JPA then provides the @OneToMany annotation for this case. @OneToMany is the parent-side of the relationship. We call this a unidirectional @OneToMany association.

When the child-side manages a relationship, we have a unidirectional @ManyToOne association. In this association, the child entity (Post) has an object reference to its parent (Blog).

This child/parent relationship is created by the use of mapping child foreign keys mapping to the parent.

In order to get the most fully functional mapping, it is best to use a unidirectional many-to-one association,

JPA Unidirectional One To Many Example

First, let’s create a model for our Blog model:

@Entity
@Table(name = "blogs")
public class Blog {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private long id;

  @Column(name = "title")
  private String title;

  @Column(name = "description")
  private String description;

  @Column(name = "published")
  private boolean published;

  @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
  @JoinColumn(name = "blog_id")
  private Set<Comment> comments = new HashSet<>();

}

The above example includes Comments in our OneToMany mapping. We use this annotation in conjunction with @JoinColumn that will create a column in the child table (Comments) storing the parent’s Id (Blog).

The orphanRemoval helps us remove children (Comments) from the database if we delete the parent (Blog)

Bidirectional vs Unidirectional Relationships

In our example, we are using a unidirectional relationship. It is important to understand the difference between a unidirectional relationship and bidirectional relationship.

This biggest difference is that bidirectional relationships provide “navigation” access in both directions.

“Navigation” in this sense is a fancy term for, you can access these model properties thru the property.

Navigational access is not always good especially if you have MANY children properties.

Unless you have hundreds or thousands of children, unidirectional is *usually* the best choice. According to Hibernate documentation, bidirectional is the best choice in most cases.

@Entity
@Table(name = "comments")
public class Comment {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @Column(name = "title"
  private String title;

  @Lob
  private String content;
}

Notice in this class we do not need to add any extra annotations because this is a unidirectional relationship.

Comments

Popular posts from this blog

Higher Order Functions in JavaScript Explained Simply

  What is a higher order function? In JavaScript, a higher-order function is a function that  takes one or more functions as arguments,  or returns a function as output. These functions are a powerful feature of the language that allow you to write concise and expressive code. The best way to learn higher order functions (and likely the most “real-world”) is to look at “map()” and “filter()”. Both take functions as arguments where the function is applied to each element in an array. Map For example, consider the  map  function, which is used to apply a function to each element of an array and return a new array containing the results. The  map   function is a higher-order function because it takes a function as its argumen t, in this case the function to apply to each element of the array. const numbers = [1, 2, 3, 4, 5]; const squares = numbers.map(x => x * x); Filter Another common higher-order function is  filter , which is used to select el...

Basic CRUD Array Operations in JavaScript

  Sometimes it pays just to stick to the basics. Here are CRUD operations for a basic array: 1. Create an element to the end of an array let clubs = ['baseball','running','computer club']; clubs.push('tennis'); console.log(clubs); 2. Delete an element from the end of an array let clubs = ['baseball','running','computer club']; const lastElement = seas.pop(); console.log(lastElement); 3. Reading an index from an element in an array let clubs = ['baseball','running','computer club']; let index = clubs.indexOf("running"); console.log(index); 4. Update an index from an element in an array let clubs = ['baseball','running','computer club']; clubs.splice(1, 0, 'tennis'); console.log(clubs);

Immutability in JavaScript

  Immutability is a popular concept not just in JavaScript, but most programming languages in general. The reason behind this of course is functional programming which gives software developers a brand new paradigm to utilize when coding. Let’s dive into the details of mutability and immutability. What is Mutability? A mutable value is one that can be changed without creating an entirely new value.   In JavaScript, objects and arrays are mutable by default, but primitive values are not.  Once a primitive value is created, it cannot be changed, although the variable that holds it may be reassigned. There is nothing wrong with mutability. Take a look at the code below: const dog = { name: 'turtle', age: 10 } // Make a copy of dog object const newDog = dog; // Changing the age of the new dog newDog.age = 12; console.log(newDog === dog); // true As you can see, we’re copying the object to another object and changing the dogs age. The problem is that the change happe...