I have 2 main entities Dog and Cat both of them have different fields except of id
and dataVersion
,
the id fields are NOT being generated by hibernate
nor the db.
the field dataVersion
is generated using @GeneratedValue
with the same db sequence .
The problem is like this i have 2 threads:
- Thread 1 Creates entity
Dog
persists it and then it sleeps for 30 seconds - Thread 2 starts 10 seconds after thread 1, thread 2 persists entity
Cat
and commits it. - Thread 1 commits after 30 seconds
What I expect the database to have is entity Dog
with dataVersion 2 and entity Cat
with dataVersion 1,
but somehow entity Dog
has dataVersion 1 and entity Cat
has dataVersion 2 .
I have searched allot on the internet about @GeneratedValue
and I found out that the value is generated when the transaction is flushed so I turned off auto flush. The flush happens only when the transaction is committed and still I didn't get the expected result.
I would like to know what is the causing for this problem.
@Entity
@Getter
@Setter
public class Dog {
@Id
private String id;
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "dataVersionGen")
@SequenceGenerator(name = "dataVersionGen", sequenceName = "DATA_VER_SEQ")
private Long dataVersion;
}
@Entity
@Getter
@Setter
public class Cat {
@Id
private String id;
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "dataVersionGen")
@SequenceGenerator(name = "dataVersionGen", sequenceName = "DATA_VER_SEQ")
private Long dataVersion;
}
This is the code that's evaluate when the start running
@Component
public class Example {
private ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
@Autowired
private DBAccessor accessor;
@PostConstruct
public void example() {
threadPoolTaskExecutor.initialize();
// Starts dog's thread
threadPoolTaskExecutor.execute(() -> {
Dog dog = new Dog();
dog.setId(UUID.randomUUID().toString());
accessor.persist(dog);
sleep(30 * SECOND);
accessor.commit();
});
// Starts dog's thread
threadPoolTaskExecutor.execute(() -> {
sleep(10 * SECOND);
Cat cat = new Cat();
cat.setId(UUID.randomUUID().toString());
accessor.persist(cat);
accessor.commit();
});
}
}