0

I'm working on a project where I need to do CRUD operations on Book and Library objects. Naturally the relationship between Book and Library is Many to One, like so:

@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class LibraryDao {

    @Id
    @GeneratedValue
    Long id;

    @OneToMany(mappedBy = "library")
    List<BookDao> book = new ArrayList<>();

} 
@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class BookDao {
    
    @Id
    @GeneratedValue
    private long id;

    @ManyToOne(fetch = FetchType.LAZY)
    private LibraryDao library;

    String name;

    public BookDao(Library library, String name) {
        this.library = library;
        this.name = name;
    }
    
}

I'm trying to keep these as separate as possible in each layer which is where my question comes from. It's easy to keep the creation and getting of Library stuff separate, but I'm finding it hard to create persist Books without mixing the two up. Mainly because I need a LibraryDAO object to create a BookDAO. Please see my comment in the BookServiceImpl class.

@Service
public class LibraryServiceImpl implements LibraryService {

    @Autowired
    LibraryRepository libraryRepository;

    @Override
    public Library getLibrary(long libraryId) {
        LibraryDao libraryDao = libraryRepository.findById(libraryId).orElseThrow(LibraryNotFoundException::new);
        return new Library(libraryDao.getId(), libraryDao.getBooks().stream().map(book -> new Book(book.getId(), book.getName())).collect(Collectors.toList()));
    }

    @Override
    public Library createLibrary() {
        LibraryDao libraryDao = libraryRepository.save(new LibraryDao());
        return new Library(libraryDao.getId(), List.of());
    }

}
@Service
public class BookServiceImpl implements BookService {

    @Autowired
    BookRepository bookRepository;

    @Autowired
    LibraryService libraryService;
    

    @Override
    public Book createBook(Long libraryId, String name) {

        //Which one below is less destructive to the MVC pattern? Either I can 
        //have a LibraryRepository in my BookService class (this feels wrong)
        //or else make libraryService.getLibrary() return a DAO object? Isn't is expected
        //that DAO objects stay in their service class?
        LibraryDao libraryDao = libraryService.getLibrary(libraryId);
        LibraryDao libraryDao = libraryRepository.findById(libraryId);

        BookDao bookDao = new BookDao(libraryDao, name);
        BookingDao saved = bookRepository.save(bookDao);

        return new Book(saved.getId(), saved.getLibraryDao().getId(), saved.getName());
     }

1 Answer 1

0

The best way is to simply have the id rather than the object. eg

class Book
{
   string LibraryId
   string BookId
   string title....
}

class Library
{
   string Id
   string Name
}

All your problems are now trivial.

class Repo
{
    List<Book> GetBooksInLibrary(libId)
    Book GetBook(bookId)
    Library GetLibraryContainingBookId(bookId)
    etc...
    void UpsertBook(book) //error libraryid x doesnt exist
    void UpsertLibrary(library)        
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.