Гибернация двунаправленных результатов JPA «один ко многим» с исключением нарушения ограничений

#java #spring #hibernate #jpa #h2

#java #весна #гибернация #jpa #h2

Вопрос:

Я начал изучать hibernate JPA и пытаюсь создать двунаправленное отношение «один ко многим», но по какой-то причине это приводит к org.hibernate.exception.ConstraintViolationException: could not execute statement

Допустим, у меня есть карта сущности и колода сущностей. И каждая колода может иметь несколько карт, но каждая карта может принадлежать только одной колоде. Я сделал это таким образом:

Это объект card:

 /**
 * Represents a card in deck.
 *
 * @author wintermute
 */
@Data
@Entity(name = "card")
@Table(name = "card")
@NamedQueries( {@NamedQuery(name = "Card.getAll", query = "SELECT c FROM card c WHERE c.containedInDeck = :deck_id"),
                @NamedQuery(name = "Card.remove", query = "DELETE FROM card c WHERE c.id = :id")})
public class Card
{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    private String containedText;

    @ManyToOne
    @JoinColumn(name = "deck_id")
    private Deck containedInDeck;
}
 

И это колода:

 /**
 * Represents card deck containing cards sorted by deck's type.
 *
 * @author wintermute
 */
@Data
@Entity
@Table(name = "deck")
public class Deck
{
    @Id
    @GeneratedValue
    private long id;
    @Column(name = "type")
    private String typeOfDeck;

    @OneToMany(mappedBy = "containedInDeck")
    @ElementCollection(targetClass = Card.class)
    private Set<Card> containedCards = new HashSet<>();
}
 

Теперь это мой репозиторий, в котором я хочу сохранить объект card:

     ...
    /**
     * @param card to persist in database.
     * @return true if operation was successful, false if operation failed.
     */
    public long add(Card card)
    {
        try
        {
            entityManager.getTransaction().begin();
            entityManager.persist(card);
            entityManager.flush();
            entityManager.getTransaction().commit();
            return card.getId();
        } catch (IllegalStateException | PersistenceException e)
        {
            log.error("Could not save entity: "   card   ", message: "   e.getMessage());
            return -1L;
        }
    }
    ...
 

Во время выполнения entityManager.flush() происходит сбой из-за нарушенного ограничения. Я не могу себе представить, почему.

Ответ №1:

Поскольку объект, на Deck который ссылается, Card#deck неуправляем и / или идентификатор, который у него есть, не существует. Если вы хотите сохранить файл Deck вместе с картой, вам необходимо настроить сохранение каскадного включения Card#deck .