Home > Software engineering >  Concurrency and JPA repository behaviour
Concurrency and JPA repository behaviour

Time:10-14

I have 2 Entities mapped with JPA

@Entity
class Table_A {

  @Id
  private Integer id;

  @Enumerated(EnumType.STRING)
  private ModuleType module;

  private String name;

  private Instant lastModifiedDate; 

  private String creator;

  @NotNull
  @Enumerated(EnumType.STRING)
  private State state;
  
  @OneToMany(fetch = FetchType.LAZY)
    @JoinColumns( value = {
      @JoinColumn(name="id_object", referencedColumnName = "id_entity", insertable = false, updatable = false),
      @JoinColumn(name="object_sub_type", referencedColumnName = "object_sub_type", insertable = false, updatable = false),
  }, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
  private List<AttributeValue> attributes;
}


@Entity
Class Table B {
@Id
  private Integer id;

  @Column(name = "id_create_user", insertable = false, updatable = false)
  private String createUser;

  @Column(name = "type_object", insertable = false, updatable = false)
  private String typeObject;


  @Column(name = "id_object", insertable = false, updatable = false)
  private Integer idTable_A;

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

  private Boolean hasCombination;
}

The entities are not related. And also I have a JPARepository interface for each one.

@Repository
public interface Table_A_Repository extends JpaRepository<Table_A, Integer>
@Repository
public interface Table_B_Repository extends JpaRepository<Table_B, Integer>

When I have 2 threads.

The first one Thread_1 read an object of "Table_A" make some operations and modify one field of the table_A object

The second Thread_2 read the same object from Table_A and makes changes on different rows of Table_B ( Table_B_Repository.saveAll( listOfTable_Bobjects) ) before Thread_1 has finished.

I see than Thread_2 override the change of Thread_1 in Table_A object.

What I don't understand is why calling Table_B_Repository.saveAll makes and update in table_A overriden the value set in the first thread, leaving it as it was.

thanks for your responses or comments.

CodePudding user response:

The problem with this implementation is that when you try to update by saveall method, you will be having all the data in Objects.

So if you are reading the data by name, so for some name there are around 4 objects and you are updating only the last object, but at the time of saving, you are not saving that only object but saving all objects that you have read previously.

In hibernate if there is some change in the data then only it will update the data in the db, so for the objects that were updated by Thread A will be considered for update by thread B and all the changes done by thread A will be overridden.

CodePudding user response:

saveAll method on repository will save the record if it is new and merge if it is not new. So if you saveAll all records, records that are changed by thread 1 will be overwritten in the persistence context by merge().

  • Related