Hi, I am trying to migrate from 4.3.6.Final to 5.1.0 Final to get java 8 date time api mapping and unrelated join entities features. But unfortunately I got an issue related with sequence generation. Here is my test:
{code} for (int i = 0; i < 50; i++) { Client client = new Client(); client.setName("Test#" + i); clientRepository.save(client); System.out.println(client.getId()); } {code}
{code} ----------------------------------------------------------------- @Entity @Table(name = "client") @Getter @Setter class Client { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "c_seq") @SequenceGenerator(name = "c_seq", sequenceName = "c_seq", allocationSize = 20) @Column(name = "ID_CLIENT") public Integer id; .... } {code}
*CREATE SEQUENCE c_seq start 1 increment 1;* --------------------------------------------------------------------------------------------------------------------- Console output: {code} Hibernate: select nextval ('c_seq') Hibernate: select nextval ('c_seq') 1,2 Hibernate: select nextval ('c_seq') -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0 org.springframework.dao.DataIntegrityViolationException: A different object with the same identifier value was already associated with the session : [igor.domain.Client#1] This exception rises cause next id after 0 was 1 and we've already Client with id 1. {code} Actually you have changed sequence strategy generation in new 5.1.0 version old: SequenceHiLoGenerator new: SequenceStyleGenerator And SequenceStyleGenerator uses PooledOptimizer. I've spent time debugging PooledOptimizer and got that it happens due to this piece of code {code} else if ( generationState.value.gt( generationState.hiValue ) ) { generationState.hiValue = callback.getNextValue(); generationState.value = generationState.hiValue.copy().subtract( incrementSize - 1 ); } {code}
But it works fine with Hibernate 4.3.6.Final Console output: {code} Hibernate: select nextval ('c_seq') 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, Hibernate: select nextval ('c_seq') 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59 Hibernate: select nextval ('c_seq') 60, 61, 62, 63, 64, 65, 66, 67, 68, 69 Hibernate: /* insert igor.domain.Client */ insert into client (age, name, id_client) values (?, ?, ?) (x50 times) {code}
As we can see everything is fine, allocationSize works and there is no exception with 4.3.6. I am really wondering about negative ids and this issue. NOTE: If I change my sequence to CREATE SEQUENCE c_seq start 1 *increment 20*; ,increment size is the same as allocationSize, it works fine : Hibernate: select nextval ('c_seq') Hibernate: select nextval ('c_seq') 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 Hibernate: select nextval ('c_seq') 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41 Hibernate: select nextval ('c_seq') 42, 43, 44, 45, 46, 47, 48, 49, 50 Hibernate: /* insert igor.domain.Client */ insert into client (age, NAME, ID_CLIENT) values (?, ?, ?) It even better then in 4.3.6 cause id starts from 1, not from 20 |
|