У меня есть вариант использования:
book
таблица до book_category
таблица с many-to-one
book_category
таблица до book
таблица с one-to-many
book
таблица с author
таблицей с many-to-many
, которая сохраняется в таблице book_author
(состоит из book_id
и author_id
)
вот как я заявляюentity
и dto
:
Книга
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "title", nullable = false)
private String title;
@Column(name = "year", nullable = false)
private String year;
@ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
@JoinTable(
name = "book_author",
joinColumns = @JoinColumn(name = "book_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "author_id", referencedColumnName = "id"))
@JsonManagedReference
private Set<Author> author;
@ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
@JoinColumn(name = "category_id", referencedColumnName = "id", nullable = false)
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
private BookCategory category;
}
Автор
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name", nullable = false)
private String name;
@Column(name = "address", nullable = false)
private String address;
@ManyToMany(
mappedBy = "author",
cascade = CascadeType.PERSIST,
fetch = FetchType.LAZY
)
@JsonBackReference
private Set<Book> book;
}
AuthorDto
public class AuthorDto {
private Long id;
private String name;
private String address;
}
BookDto
public class BookDto {
private Long id;
private String title;
private String year;
private Set<AuthorDto> author;
private String category;
}
BookServiceImplementation
@Override
public BookDto save(BookDto bookDto) throws Exception {
try {
Book book = new Book();
generateBook(book, bookDto);
} catch (Exception e) {
e.printStackTrace();
throw new Exception(e);
}
return null;
}
@Override
public BookDto editById(Long id, BookDto bookDto) throws Exception {
try {
Book book = bookDao.findById(id).get();
generateBook(book, bookDto);
} catch (Exception e) {
e.printStackTrace();
throw new Exception(e);
}
return null;
}
private BookDto generateBook(Book book, BookDto bookDto) throws Exception {
try {
BeanUtils.copyProperties(bookDto, book, "id", "author", "category");
BookCategory bookCategory = bookCategoryDao.findByCategory(bookDto.getCategory());
Set<Author> dataAuthor = new HashSet<Author>();
Set<AuthorDto> dataAuthorDto = new HashSet<AuthorDto>();
bookDto.getAuthor().iterator().forEachRemaining(dataAuthorDto::add);
for (AuthorDto authorDto : dataAuthorDto) {
Author author = authorDao.findByNameAndAddress(authorDto.getName(), authorDto.getAddress());
if (null == author) {
author = new Author();
System.out.println("null"); // this printed, means that author is null
BeanUtils.copyProperties(authorDto, author, "id");
}
System.out.println(author.getName()); // this printed, the copied of the name from dto to entity
dataAuthor.add(author);
}
book.setAuthor(dataAuthor);
book.setCategory(bookCategory);
bookDao.save(book);
} catch (Exception e) {
e.printStackTrace();
throw new Exception(e);
}
return null;
}
вот примерjson
для ввода данных для save/update
книга:
{
"title": "book1",
"year": "2013",
"author": [
{
"name": "john",
"address": "LA"
}
],
"category": "science"
}
Текущее поведение
- сохранить новый
book
, с несколькими author
, если author
в json
существует в дБ, он не будет сохранен как новые данные.Но если author
в json
не существует в дБ, он будет сохранен в таблице авторов.Скажем, у меня есть книга с названием book1
.book1
имеют john
и mary
в качестве author
.john
уже существует в таблице author
.Таким образом, если вставить данные, john
не сохранится снова в таблице, будет сохранено только mary
.
Проблема
- Проблемаэто когда
edit/update
.Если у меня book2
с alex
в качестве author
.Затем я хочу изменить author
на john
, этот случай может работать , потому что john
уже существует в дБ.Но если я изменю alex
на lucy
(который lucy
равен не существует в таблице авторов), он выдаст ошибку.Вот ошибка: Caused by: org.postgresql.util.PSQLException: ERROR: null value in column "address" violates not-null constraint. Detail: Failing row contains (17, null, null).
Что здесь не так?