Получение ошибки, вызванной: org.hibernate.AnnotationException: использование @OneToMany или @ManyToMany для таргетинга на не отображенный класс

Я новичок на арене JPA/Hyperjaxb. Моя цель - создать отображение "многие ко многим" между таблицами "Автор" и "Книга" (база данных postgres).

В базе данных - таблица Автора имеет столбцы - id, name, а в таблице Book есть столбцы - id, title. У меня есть таблица соединения (связывания) AUTHORS_BOOKS, в которой есть столбцы aid, bid (где помощь сопоставляется с полем id в таблице Author, а bid сопоставляется с полем id в таблице Book).

Мы представляем веб-сервис (давайте не будем зацикливаться на том, почему веб-сервис), чтобы клиенты могли запрашивать / писать по авторам и книгам. Для веб-сервиса я создаю pojos, используя нотации hyperjaxb (опять же, как это было).

Вот мой файл types.xsd:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<xs:complexType name="author">
    <xs:sequence>
        <xs:element name="id" type="xs:long"/>
        <xs:element name="name" type="xs:string" />
        <xs:element name="books" type="tns:book" minOccurs="0" maxOccurs="1000"/>
    </xs:sequence>
</xs:complexType>

<xs:complexType name="book">
    <xs:sequence>
        <xs:element name="id" type="xs:long"/>
        <xs:element name="title" type="xs:string"/>
        <xs:element name="authors" type="tns:author" minOccurs="0" maxOccurs="1000"/>
    </xs:sequence>
</xs:complexType>

Вот файл bindings.xjb:

<?xml version="1.0" encoding="UTF-8"?>

<jaxb:bindings schemaLocation="sampletypes.xsd"
    node="/xs:schema">
    <jaxb:bindings node="xs:complexType[@name='author']">
        <hj:entity>
            <orm:table name="AUTHORS">
                <orm:unique-constraint>
                    <orm:column-name>NAME</orm:column-name>
                </orm:unique-constraint>
            </orm:table>
        </hj:entity>        
    </jaxb:bindings>

    <jaxb:bindings node="xs:complexType[@name='cocom']">
        <hj:entity>
               <orm:table name="BOOKS">
                     <orm:unique-constraint>
                            <orm:column-name>NAME</orm:column-name>
                     </orm:unique-constraint>
               </orm:table>
        </hj:entity>        
     </jaxb:bindings>

    <jaxb:bindings
            node="xs:complexType[@name='author']//xs:element[@name='books']">
                   <hj:many-to-many name="books">
                         <orm:join-table name="AUTHORS_BOOKS">
                                <orm:join-column name="aid" referenced-column-name="ID" />
                                <orm:inverse-join-column name="bid" referenced-column-name="ID" />
                         </orm:join-table>
                   </hj:many-to-many>
     </jaxb:bindings>

     <jaxb:bindings
                node="xs:complexType[@name='book']//xs:element[@name='authors']">
                       <hj:many-to-many name="authors" mappedBy="books">
                       <hj:cascade>
                       <hj:cascade-persist/>
                       </hj:cascade>
                       </hj:many-to-many>
      </jaxb:bindings>

    <jaxb:bindings
        node="xs:complexType[@name='author']//xs:element[@name='id']">
        <hj:id>
            <orm:generated-value strategy="AUTO" />
        </hj:id>
    </jaxb:bindings>

    <jaxb:bindings
        node="xs:complexType[@name='book']//xs:element[@name='id']">
        <hj:id>
            <orm:generated-value strategy="AUTO" />
        </hj:id>
    </jaxb:bindings>

</jaxb:bindings>

Вот (часть) сгенерированный Author.java:

 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "author", propOrder = {
"id",
"name",
"books"
})
@Entity(name = "Author")
@Table(name = "AUTHOR", uniqueConstraints = {
@UniqueConstraint(columnNames = {
    "NAME"
})
})
 @Inheritance(strategy = InheritanceType.JOINED)
 public class Author
implements Serializable, Equals, HashCode, ToString
{

 //some othe stuff

@ManyToMany(targetEntity = Book.class, cascade = {
    CascadeType.ALL
})
@JoinTable(name = "AUTHORS_BOOKS", joinColumns = {
    @JoinColumn(name = "aid", referencedColumnName = "ID")
}, inverseJoinColumns = {
    @JoinColumn(name = "bid", referencedColumnName = "ID")
})
public List<Book> getBooks() {
    if (books == null) {
        books = new ArrayList<Book>();
    }
    return this.books;
}

}

Вот (часть) сгенерировать Book.java:

 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "book", propOrder = {
"id",
"title",
"authors"
})
@Entity(name = "Book")
@Table(name = "BOOK", uniqueConstraints = {
@UniqueConstraint(columnNames = {
    "NAME"
})
})

@Inheritance(strategy = InheritanceType.JOINED)
public class Book
implements Serializable, Equals, HashCode, ToString
{

private final static long serialVersionUID = 1L;
protected long id;
@XmlElement(required = true)
protected String title;
protected List<Author> authors;

/**
 * Gets the value of the id property.
 * 
 */
@Id
@Column(name = "ID", scale = 0)
@GeneratedValue(strategy = GenerationType.AUTO)
public long getId() {
    return id;
}

/**
 * Sets the value of the id property.
 * 
 */
public void setId(long value) {
    this.id = value;
}

@Basic
@Column(name = "NAME_", length = 255)
public String getName() {
    return name;
}

public void setName(String value) {
    this.name = value;
}

@ManyToMany(targetEntity = Book.class, cascade = {
    CascadeType.ALL
})
@JoinTable(name = "AUTHORS_BOOKS", joinColumns = {
    @JoinColumn(name = "PARENT_AUTHOR_ID")
}, inverseJoinColumns = {
    @JoinColumn(name = "CHILD_BOOK_ID")
})
public List<Book> getBooks() {
    if (books == null) {
        books = new ArrayList<Book>();
    }
    return this.books;
}

Я не уверен, что я делаю неправильно, но я получаю следующую ошибку при развертывании файла war в tomcat (7.0.34, также пробовал пару других версий 7.0.x)

Error Message: 
Caused by: org.hibernate.AnnotationException: Use of @OneToMany or @ManyToMany targeting an unmapped class:com.mycompany.Author.books[com.mycompany.Book]

Я искал в Интернете ответы, и либо нет решений, либо большинство ошибок было связано с отсутствием поля @Entity или @Id или targetEntity в теге @ManyToMany. Я мог бы действительно использовать некоторые указатели на это! Очень ценю ваше время и помощь! Благодарю.

3 ответа

Решение

Спасибо всем за помощь! Оказывается, это была проблема с отображением. В файле /src/main/resources/persistence.xml я забыл добавить полный путь к классу (для Book.java), чтобы Hibernate не смог его найти. Так что это было скорее вопросом интеграции. Еще раз спасибо за помощь!

Вопрос в том, почему Hibernate считает, что com.mycompany.Book не отображен.

Я бы заподозрил проблему с дублирующимися классами или чем-то в этом роде. Попробуйте сначала запустить изолированный тест туда и обратно (HJ3 обеспечивает некоторую поддержку). Это явно не имеет ничего общего с версией Tomcat и так далее.

Было то же самое. Оказывается, я был достаточно глуп, чтобы написать List в классе oneToMany вместо List...

Другие вопросы по тегам