Mappingeasy0-2 years
Code adds a new `Book` to `author.getBooks()` and persists both. Every assertion in the method passes — `author.getBooks()` contains the book — but in the database `book.author_id` is `NULL`. No error was thrown. What went wrong?
Only one side of a bidirectional relationship writes the foreign key: the owning side. @OneToMany(mappedBy = "author") on Author.books says 'Book owns this relationship; this collection is only a view of it'. The code updated the view and never set book.author, so when Hibernate wrote the book it read book.author, found null, and wrote null. In memory the object graph is perfect, which is why the assertions pass; in the database there is no relationship at all. The fix is a helper on the entity that always sets both sides at once.
PreviousA `@Transactional` service method loads an `Author`, calls `setName(...)`, and returns. There is no `save()` anywhere, yet the log shows `update Author set name=? where id=?`. Where did that UPDATE come from, and is adding `repository.save(author)` "to be safe" a good idea?Next A repository declares `List<User> findByEmaill(String email)` — a typo. When does that fail: at compile time, at startup, on the first call, or never? And at what point should a derived query method stop being a method name?
An entity's `equals`/`hashCode` are generated from its `@GeneratedValue` id. A new `Tag` is added to a `HashSet`, persisted, and then `set.contains(tag)` returns `false` — even though `set.size()` is 1 and iterating returns that exact object. Why, and what should an entity's `equals`/`hashCode` be based on?`Category.products` is a `@OneToMany(mappedBy = "category")`, and someone adds `orphanRemoval = true` "for consistency" with `Order.lines`, which has it. The next day, an admin un-categorises a product (removes it from the category's collection and clears `product.category`), and the product row is deleted from the database. No `remove()` was called anywhere. Explain the difference between `CascadeType.REMOVE` and `orphanRemoval`, and why only one of them fired here.