我正在尝试在连接表中具有附加属性的两个实体之间实现MANY_TO_MANY关系。 我找到了以下答案: how-to-do-a-many-to-many-relationship-in-spring-roo-with-attributes-within-de-relationship 但我没有尝试将提供的解决方案适应我的方案:
目前我有一个直接的MANY_TO_MANY关系:
# book:
entity jpa --class ~.domain.Book --testAutomatically
field string --fieldName title --notNull
field string --fieldName subtitle --notNull
field string --fieldName description
# n:m relationship to author
field list --fieldName authors --type ~.domain.Author --cardinality MANY_TO_MANY
# author:
entity jpa --class ~.domain.Author --testAutomatically
field string --fieldName firstName --notNull
field string --fieldName lastName --notNull
按预期工作,但我需要让作者订购。我想通过定义关系表并添加一个像'sequence'这样的整数字段来实现这一目标,但是当我尝试在Book中定义多对多关系时我陷入困境:
entity jpa --class ~.domain.BookAuthorOrdered --table book_author_ordered
# the additional field to store sequence of authors:
field number --fieldName authorSequence --type java.lang.Integer --notNull
# reference to book:
field reference --fieldName bookId --type ~.domain.Book --cardinality MANY_TO_ONE
# reference to author:
field reference --fieldName authorId --type ~.domain.Author --cardinality MANY_TO_ONE
任何人都可以给我一个提示如何在Book中定义属性,以便我使用上面定义的连接表获得已排序作者的列表?这是我尝试的东西:
# complete the relationship
focus --class ~.domain.Book
field list --type ~.domain.BookAuthorOrdered --fieldName orderedAuthors --cardinality ONE_TO_MANY --mappedBy bookId
答案 0 :(得分:1)
尝试将@OrderBy注释添加到实体字段(在 .java 文件中)。例如:
@ManyToMany
@OrderBy("lastName ASC, firstName ASC")
private List<Author> authors;
答案 1 :(得分:0)
我找到了一个或多或少的解决方案来解决我的问题,但它仍然有一些缺点。它主要来自上述答案: How to do a many-to-many relationship in spring Roo, with attributes within de relationship?
使用表book和author的id作为组合主键手动创建连接表: 袋鼠&GT; entity jpa --class~ .domain.BookAuthorOrdered --table book_author_ordered --identifierType~.domain.BookAuthorOrderedId 字段编号--fieldName authorSequence --type java.lang.Integer --notNull
然后编辑生成的id类BookAuthorOrderedId并添加组合主键:
@RooToString
@RooEquals
@RooIdentifier
public final class BookAuthorOrderedId {
@ManyToOne
@JoinColumn(name="book_id", insertable = false, updatable = false)
private Book book;
@ManyToOne
@JoinColumn(name="author_id", insertable = false, updatable = false)
private Author author;
}
现在出现了我感觉不好的部分,因为它看起来像是一种解决方法。在book实体中,我为作者推送了getter方法,并将其替换为连接表的查询:
public List<Author> getAuthors()
{
// return Author.findAllAuthorsOfBook(this);
System.out.println("getAuthors()");
EntityManager em = new Book().entityManager;
TypedQuery<Author> q = em.createQuery("SELECT o FROM Author AS o WHERE o.id IN ( SELECT OA.id.author FROM eu.books2ebooks.roomanova.domain.BookAuthorOrdered OA where OA.id.book = :book ) ", Author.class);
q.setParameter("book", this);
List<Author> authorList = q.getResultList();
//this.setAuthors(authorList);
return authorList;
}
和一种直接为新添加的作者获取bean值的方法:
public List<Author> getAddedAuthors() {
return this.authors;
}
然后我不得不操纵书籍控制器来调用自编写的方法来插入/更新连接表(在创建/更新/ ......):
public static void setOrderedBookAuthors(Book book, List<Author> authors) {
// delete all associated authors of book:
List<BookAuthorOrdered> bookAuthorOrdereds = BookAuthorOrdered.findAllBookAuthorOrdersOfBook(book);
for (BookAuthorOrdered bookAuthorOrdered : bookAuthorOrdereds) {
log.info("removing book author: " + printAuthor(bookAuthorOrdered.getId().getAuthor()));
bookAuthorOrdered.remove();
}
if ( authors == null )
{
log.info("ordered authors: null. nothing to insert.");
return;
}
log.info("inserting sorted authors: ");
Integer authorSequence = 1;
for (Author author : authors) {
log.info("inserting book author sorted: " + printAuthor(author) + " as no " + authorSequence);
BookAuthorOrdered bookAuthorOrdered = new BookAuthorOrdered();
bookAuthorOrdered.setAuthorSequence(authorSequence);
BookAuthorOrderedId id = new BookAuthorOrderedId(book, author);
bookAuthorOrdered.setId(id);
log.info("book author ordered: " + bookAuthorOrdered);
bookAuthorOrdered.persist();
authorSequence++;
}
}
到目前为止有效,但感觉必须有更优雅的方式...