I noticed that when I have a ManyToMany relationship and @Version field on an entity then when I try to add some other entitys that have relationship with this entity hibernate triggers an update on the entity and updates the version.
This could be what I want but what if I dont want to update the version every time a relationship changes. Is there any way to achieve this when using @Version?
I have a small dummy example:
@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@EntityListeners(AuditingEntityListener.class)
public class Shop {
@NotNull
@LastModifiedDate
@Column(name = "last_updated")
private Instant lastUpdated;
@NotNull
@Version
@Column(name="version")
private Long version;
@Id
@SequenceGenerator(name = "shop_id_seq", sequenceName = "shop_id_seq", allocationSize = 1)
@GeneratedValue(
generator = "shop_id_seq",
strategy = GenerationType.SEQUENCE
)
private Long id;
private String name;
@ManyToOne()
private Location location;
@OneToMany(mappedBy = "shop")
private List<ShopProduct> shopProducts;
@ManyToMany()
@JoinTable(
name="shop_worker",
joinColumns = @JoinColumn(name = "shop_id"),
inverseJoinColumns = @JoinColumn(name = "worker_id")
)
private Set<Worker> workers = new HashSet<>();
public void addWorker(Worker worker) {
workers.add(worker);
worker.getShops().add(this);
}
public void removeWorker(Worker worker) {
workers.remove(worker);
worker.getShops().remove(this);
}
}
@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@EntityListeners(AuditingEntityListener.class)
public class Worker {
@NotNull
@LastModifiedDate
@Column(name = "last_updated")
private Instant lastUpdated;
@Id
@SequenceGenerator(name = "worker_id_seq", sequenceName = "worker_id_seq", allocationSize = 1)
@GeneratedValue(
generator = "worker_id_seq",
strategy = GenerationType.SEQUENCE
)
private Long id;
private String name;
@ManyToMany(mappedBy = "workers")
public Set<Shop> shops = new HashSet<>();
public void addShop(Shop shop) {
shops.add(shop);
shop.getWorkers().add(this);
}
public void removeShop(Shop shop) {
shops.remove(shop);
shop.getWorkers().remove(this);
}
}
@Test
@Transactional
void testAddingShopToWorker(){
System.out.println("TEST SETUP");
var shop = new Shop();
shop.setName("Shop1");
em.persist(shop);
em.flush();
em.clear();
System.out.println("TEST BEGINS");
Shop myShop = em.find(Shop.class, 1L);
var worker = new Worker();
worker.setName("John");
worker.addShop(myShop);
workerRepository.save(worker);
em.flush(); // hibernate triggers update on shop even though its not needed
}
from logs: Hibernate: update shop set last_updated=?, location_id=?, name=?, version=? where id=? and version=?
Note: When you comment out the version field then hibernate wont trigger the update. It just makes an insert to the intermediery table like expected.