Hibernate - отображение коллекций с авто FK - PullRequest
0 голосов
/ 22 мая 2018

У меня проблема с отношениями ManyToSomething.Я не могу сделать аннотацию, которая генерирует правильно FKs.Возможно, это плохая идея (например, сохранение только одной сущности с каскадом).

Давайте разберем этот упрощенный код где-то в программе:

    Conversation conversation = new Conversation(){{
        getMessages().add(new Message());
    }};

    session.persist(conversation);

    // OR LIKE THIS:

    Message message = new Message();     
    Conversation conversation = new Conversation();

    message.setConversation(conversation);

    session.persist(message);

А затем упростим аннотацию Hibernate:

@Entity
public class Message{

  @Id
  @GeneratedValue
  private int id;

  @ManyToOne
  private Conversation conversation;

}

@Entity
public class Conversation{

  @Id
  @GeneratedValue
  private int id;

  @OneToMany(mappedBy = "conversation", cascade = CascadeType.PERSIST)
  private Set<Message> messages = new HashSet<Message>();

  public Set<Message> getMessages() {
    return messages;
  }
}

Таким образом, FK для разговора должен храниться в сообщении (один разговор - много сообщений).Но когда код Java запускается, база данных записывает только новые идентификаторы, без FK на стороне разговора.Как это возможно?

ОБНОВЛЕНИЕ 1 (все еще не повезло):

@Entity
@Table(name = "conversation_message")
public class Message{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(unique = true, nullable = false)
    private int id;

    @ManyToOne
    @JoinColumn(name = "conversation_id", insertable = false, updatable = false)
    private Conversation conversation;

... (other fields + getters/setters without annotation)
}

@Entity
public class Conversation{ 

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(unique = true, nullable = false)
    private int id;

    @OneToMany(mappedBy = "conversation", cascade = CascadeType.PERSIST)
    private Set<Message> messages = new HashSet<Message>();

... (other fields + getters/setters without annotation)
}

ОБНОВЛЕНИЕ 2 (с примечанием ОБНОВЛЕНИЕ 1), на этом:

Conversation conversation = new Conversation();
conversation.getMessages().add(new Message(){{
    setConversation(conversation);
    setText("test");
}});

session.persist(conversation);

Hibernateжурнал:

insert 
        into
            conversation
            (course_id, created, name, replies, user_id) 
        values
            (null, null, null, true, null)

insert 
        into
            conversation_message
            (file, sent, text) // There is missing conversation_id at all
        values
            (null, null, "Test")

1 Ответ

0 голосов
/ 23 мая 2018

Я не вижу ни одного поля Id в вашем коде ... То, что вы, вероятно, пропустили, это в обоих случаях:

private Integer id;  

@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "ID", unique = true, nullable = false)
public Integer getId() {
    return this.id;
}

Тогда оно будет сгенерировано автоматически при сохранении.

ОБНОВЛЕНИЕ: также, чтобы иметь внешний ключ в таблице Messages, вам нужно это:

@JoinColumn(name = "conversation_id", insertable = false, updatable = false)
@ManyToOne
private Conversation conversation;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...