#JPA Relationship Annotations Update

1 messages · Page 1 of 1 (latest)

tawdry deltaBOT
#

@untold seal has a question:

elielielieli

If you use @ManyToOne and @OneToMany JPA annotation on two classes this doesn't mean it will automatically update both sides right

#

<@&987246399047479336> please have a look, thanks.

untold seal
#

like

class Book {
  @ManyToOne
  private Bookshelf bookshelf;

  public void setBookshelf(Bookshelf newBookshelf) {
    this.bookshelf = newBookshelf;
  }
}

class Bookshelf {
  @OneToMany
  private List<Book> books = new ArrayList<>();

  public void addBook(Book book) {
    books.add(book);
    book.setBookshelf(book);
  }
}
tawdry deltaBOT
untold seal
#

This is what basically everyone online says to do

#

but it seems like you can create an inconsitency if you ever call setBookshelf directly

#

Or if you have a Book that's already in a Bookshelf and you add it to another, that causes an issue too

zinc breach
#

updates will be reflected if the entities are persistent

#

if your Book is persistent, and you call setBookshelf, you will create a bookshelf record in the database when transaction commits

untold seal
#

obv not in the db

#

but in the actual objects references

#

it won't be reflected

#

unless you refresh them through db

zinc breach
#

I think the issue here is not specifying manually how the entities are joined

#

the book relationship should have a @JoinColumn

#

and bookshelf should have mappedBy

untold seal
#

ignore the JPA aspect for now

#

I just mean the actual objects references will be incorrect

#
Book book1 = new Book();
Bookshelf bookshelf1 = new Bookshelf();
Bookshelf bookshelf2 = new Bookshelf();

bookshelf1.addBook(book1);
bookshelf2.addBook(book2);
tawdry deltaBOT
untold seal
#

regardless of what JPA annotations you use, this will make it so both bookshelfs "have" the book, which shouldn't be possible

#

but to avoid that you have to do a whole disgusting mess of code

#

So I'm assuming people just avoid doing that

zinc breach
#

because those entities are detached from persistence context

untold seal
#

yeah

#

I'm not talking about the persistence context

zinc breach
#

you're asking to make JPA work without JPA

#

persistence context is part of it

untold seal
#

even with JPA annotations

#

it would still require a refresh right?

zinc breach
#

if you operate with attached entities only, it should be fine

#

Hibernate has caches and can return you a cached instance when you query it from a db

#

it also creates proxies for your entities which can do 3 billion things when you call getters/setters on them

untold seal
#
Book book1 = new Book();
Bookshelf bookshelf1 = new Bookshelf();
Bookshelf bookshelf2 = new Bookshelf();

bookshelf1.addBook(book1);
bookshelf2.addBook(book1);

bookshelf1.getBooks()
tawdry deltaBOT
untold seal
#

Ok so assuming everything is in the persistence context here

#

are the changes reflected when we call getBooks?

zinc breach
#

what's book2?

untold seal
#

where are you seeing book2?

zinc breach
untold seal
#

oops

#

my bnad

#

editted

untold seal
zinc breach
#

whats book, you only have book1 pepekek

untold seal
#

oh mann

#

it's late

#

lol

#

changed again

zinc breach
#

I've not dived into hibernate specifics this much, but it's very possible that it will fetch bookshelf1 from cache and empty out its books when you add it to bookshelf2

#

it's better to try it out, but definitely set up annotations properly