Things you should know while using JPA

Things you should know while using JPA

Thanks to the original writer and article :

https://medium.com/@amitkumar88265/ten-things-you-should-know-while-using-jpa-89ec52d09d7d

All the examples in this blog have been created with a spring boot project with spring data JPA in Java.

  1. Use?JOIN FETCH or EntityGraph?to solve the N+1 Select problem. If you don’t know about this, read blog?which covers it in depth.
  2. Use Set instead of List while defining many-2-many relations. Because if you delete or insert an entity object in this List then instead of one query to delete or insert, spring data JPA will drop all elements of List and then reinsert the concerning objects again.

Let us understand that with an example given below:-

@Entity
public class Person {

 @Id
 @GeneratedValue(strategy = GenerationType.AUTO)
 private Long id;
 private String name;
 private Integer age;
 
 @ManyToMany()
 private List<Address> addresses;
}

@Entity
public class Address {
 @Id
 @GeneratedValue(strategy = GenerationType.AUTO)
 private Integer id;
 private String city;
 private String state;
 private String country;
}
@Transactional
@Service
public class PersonService {
 @Autowired
 private PersonRepository personRepository;
 @Autowired
 private AddressRepository addressRepository;
public void update() {
 Person person = personRepository.findByName(“test”);
 Address address = new Address();
 Address saved = addressRepository.save(address );
 person.getAddresses().add(saved);
 }
}        

Queries fired are :-

No alt text provided for this image

So what happens above is that first select query is fired to load person by name and second select query to load all addresses associated with the person which already has five addresses associated with that. After that one new address is created. And the entire address of that person is dropped and the concerned objects(5+1 new address) are inserted again. We can easily avoid it if we use Set instead of List. Same goes when we delete an item from the list.

3. For write operation we should load entity classes from DB but for read operation always use projection unless it is necessary to load entity class. The reason behind this is that when we load entity objects from DB then JPA starts the entity management lifecycle to detect changes on entities and at the end of transaction it flushes out all changes to DB, resulting in poor performance during read operation.

4. From point number 4, it is evident that JPA entity management lifecycles always do dirty checks to detect changes done on entities in that transaction, so need to use?save(Entity entity)?during update of any entity object.

@Transactional
@Service
public class PersonService {
 public void updateName(Long id, String name) {
 Person person = personRepository.findById(id)
                   .orElseThrow(EntityNotFoundException::new);
 person.setName(name);
 personRepository.save(person);// no need of it 
 }
}        

5. In a bidirectional one-2-one mapping, always use?mappedBy?in one of the classes, otherwise JPA will create foreign keys in both tables.

You can see the image below in which alter table queries to create foreign keys on both tables are fired.

No alt text provided for this image

Here we have removed one foreign key by using the?mappedBy?attribute.


No alt text provided for this image

6. Always use?@JoinColum?on unidirectional one-2-many relationships, otherwise JPA will create a linking table instead of storing foreign keys in many side of the relationship.

A Linking table?person_addresses?is created when?@JoinColumn?is?not used.

No alt text provided for this image

No Linking table but instead a foreign key in the address table has been created when?@JoinColumn?is used.

No alt text provided for this image

7. In a bidirectional one-2-many mapping always use?mappedBy?on the inverse side of relationships, otherwise JPA will create a linking table instead of storing foreign keys in many side of the relationship.

A Linking table?person_addresses?has been created when?mappedBy?is not used.


No alt text provided for this image

No Linking table but instead a foreign key in the address table has been created when?mappedBy?is used.

No alt text provided for this image

8. Always use?@JoinTable?and?mappedBy?on bidirectional many-2-many relationships, otherwise a two linking table will be created instead of two tables and one linking table.

Two linking tables are created when bi-directional @ManyToMany relationship has been created without?@JoinTable.

No alt text provided for this image

Only one linking table is created when?@JoinTable?is used.

No alt text provided for this image

9. Don’t use?@Column?on fields of entity classes if you don’t want to specify some other properties. It makes no sense, your application will run smoothly without it as well.

@Entity
public class Sample {
 @Column // no need of this annotation
 private String value;
}        

10. If class is final or has a private no-args constructor then lazy load won’t work.

Thanks for reading.

Keep Learning!

Nouha?la E.

?? Tech Lead | Business Analyst | HRIS Specialist HCM Oracle ??

2 年
Vugar Mammadli

Software Engineer ?? && Instructor at Cybernet LLC

2 年

??

回复

要查看或添加评论,请登录

Omar Ismail的更多文章

社区洞察

其他会员也浏览了