Как мне сопоставить этот составной первичный ключ? - PullRequest
1 голос
/ 04 февраля 2020

Я создаю сайт социальной сети с пружиной, и у меня проблема с составными первичными ключами. У меня есть таблицы User, Post и PostLike, и мне нужно отслеживать, кому из пользователей понравились какие сообщения. У меня также есть отношение UserData и Post, которое сообщает мне автора сообщения, но это не вызывает никаких проблем. По сути, моя таблица PostLike должна содержать столбцы post_id и user_id, и они должны служить составным первичным ключом.

Я попытался сделать это, создав встраиваемый объект PostLikeId:

Мой класс PostLikeId:

@Embeddable
public class PostLikeId implements Serializable {

    @Column(name = "post_id")
    private Post post;

    @Column(name = "user_id")
    private UserData user;

    // getters and setters

}

Класс My PostLike:

@Entity
@Table(name = "post_like")
public class PostLike {

    @EmbeddedId
    private PostLikeId id;

    //getters and setters
}

Класс My Post:

@Entity
@Table(name = "post")
public class Post {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "post_id_seq_generator")
    @SequenceGenerator(name = "post_id_seq_generator", sequenceName = "post_id_seq", allocationSize = 10)
    @Column(name = "id", updatable = false)
    private Long id;

    @OneToMany(cascade = CascadeType.ALL,
            orphanRemoval = true
    )
    @JoinColumns({
            @JoinColumn(name = "post_id",
                    referencedColumnName = "post_id"),
            @JoinColumn(name = "user_id",
                    referencedColumnName = "user_id")
    })
    private List<PostLike> likes = new ArrayList<>();

}

... и мой класс UserData:

@Entity
@Table(name = "user_data")
public class UserData {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_data_id_seq_generator")
    @SequenceGenerator(name = "user_data_id_seq_generator", sequenceName = "user_data_id_seq", allocationSize = 10)
    @Column(name = "id", updatable = false)
    private Long id;

    @OneToMany(
            mappedBy = "user",
            cascade = CascadeType.ALL,
            orphanRemoval = true
    )
    private List<Post> posts = new ArrayList<>();

    @OneToMany(
            mappedBy = "id",
            cascade = CascadeType.ALL,
            orphanRemoval = true
    )
    private List<PostLike> likedPosts = new ArrayList<>();

Когда я пытаюсь запустить и отобразить это, я получаю следующее исключение:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Unable to map collection com.budano.SocialStudent.model.Post.likes
.
.
.
Caused by: org.hibernate.AnnotationException: Unable to map collection com.budano.SocialStudent.model.Post.likes
.
.
.
Caused by: org.hibernate.cfg.RecoverableException: Unable to find column with logical name: post_id in org.hibernate.mapping.Table(public.post) and its related supertables and secondary tables

Может кто-нибудь объяснить, что говорит мне этот журнал и как я должен подойти к этой проблеме? Спасибо!

1 Ответ

1 голос
/ 04 февраля 2020

Этот подход вы можете попробовать:

PostLikeId:

@Embeddable
public class PostLikeId implements Serializable {

    @Column(name = "post_id")
    private Long postId; // corresponds to PK type of Post

    @Column(name = "user_id")
    private Long userId; // corresponds to PK type of User

    // ...

}

PostLike:

@Entity
@Table(name = "post_like")
public class PostLike {

    @EmbeddedId
    private PostLikeId id;

    @MapsId("postId") // maps postId attribute of embedded id
    @ManyToOne
    private Post post;

    @MapsId("userId") // maps userId attribute of embedded id
    @ManyToOne
    private UserData user;

    // ...
}

Сообщение:

@Entity
@Table(name = "post")
public class Post {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "post_id_seq_generator")
    @SequenceGenerator(name = "post_id_seq_generator", sequenceName = "post_id_seq", allocationSize = 10)
    @Column(name = "id", updatable = false)
    private Long id;

    @ManyToOne
    private UserData user;

    @OneToMany(mappedBy = "post", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<PostLike> likes = new ArrayList<>();

    // ...
}

UserData:

@Entity
@Table(name = "user_data")
public class UserData {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_data_id_seq_generator")
    @SequenceGenerator(name = "user_data_id_seq_generator", sequenceName = "user_data_id_seq", allocationSize = 10)
    @Column(name = "id", updatable = false)
    private Long id;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Post> posts = new ArrayList<>();

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<PostLike> likedPosts = new ArrayList<>();

    // ...
}

Производные идентификаторы обсуждаются (с примерами) в JPA 2.2 spe c в разделе 2.4.1.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...