Hi!
I’m trying to implement optimistic locking using @jakarta.persistence.Version
and I got weird behaviour: version is incremented 2 times from the time of
fetching until the time right after the entity is persisted with save().
Each product (Article) has its own so called TextID which is used to build final URL; e.g., “Gluten-free pasta 500 g” gives “gluten-free-pasta-500-g”. Because more than one product can have the same name, I have to check for duplicates, and if previously added pasta is found (e.g., different manufacturer), the suffix is added to TextID (“-1”) and it becomes “gluten-free-pasta-500-g-1”.
To achieve that, I have to issue a search accross existing products, and that causes Article version to increment.
Why does entity search/load trigger version incremenataion?
What am I doing wrong here?
At the beginning I had the same problem with the store that sells the product (Provider) because each price has its Provider attached (Article → PriceInfo → Provider).
I fixed that using entity manager although I prefer Hibernate search as everything else is fetched with it:
@PersistenceContext
private EntityManager entityManager;
// ...
final Provider provider =
this.entityManager.getReference( priceInfoDTO.getProviderDTO().getId() );
The case with TextID cannot be fixed this way because I have to filter by TextID value and not by entity id or any other id.
Technical:
- Java 21
- Hibernate 7.3.0.Final
- Hibernate Search 8.3.0.Final
public abstract class BaseEntity implements Serializable {
// ...
@jakarta.persistence.Version
@Column( nullable = false )
private int version;
// ...
}
@Entity
class Article extends BaseEntity {
// ...
@OneToMany( mappedBy = "article", fetch = FetchType.LAZY )
@IndexedEmbedded @JsonManagedReference
@AssociationInverseSide(
inversePath = @ObjectPath(
@PropertyValue( propertyName = "priceInfo" )
)
)
private Set<PriceInfo> priceInfos = new HashSet<>();
// ...
}
@Entity
class PriceInfo extends BaseEntity {
// ...
@Reference
@JsonBackReference
@ManyToOne( fetch = FetchType.LAZY )
@IndexedEmbedded( includePaths = {
"id", "name", "shortName", "description", "searchAid", "tags.name",
"tags.searchAid", "barcodes", "manufacturer.name",
"manufacturer.shortName", "manufacturer.description",
"manufacturer.searchAid"
} )
private Article article;
@Reference @JsonBackReference
@ManyToOne @IndexedEmbedded
private Provider provider;
// ...
}