JPA и настройка базы данных для таблицы ассоциации - PullRequest
0 голосов
/ 01 апреля 2020

Я немного растерялся, как мне настроить свою базу данных и сущности в jpa для того, что я пытаюсь сделать.

У меня есть таблица Attachments, в которой содержатся загруженные данные вложения, такие как оригинальное имя, сохраненное с uid, дата сохранена и т. Д. c.

Несколько других таблиц могут иметь Attachments и более одной таблицы на запись.

Таким образом, для каждой таблицы, которая может иметь вложение, у меня будет таблица ассоциации с идентификатором и идентификатором вложения.

Attachments
-----------
ID 
Original Name
Saved Name


User
-----------
Id
Name

Dog
-----------
Id
Breed
Name

Dog_Attachments
----------------
dog_id
attachment_id

User_Attachments
----------------
user_id 
attachment_id 

Так что я думаю, что это правильный способ настройки базы данных ... Но тогда как мне настроить объекты JPA?

@Entity
@Table(name = "User")
public class UserEntity  {
     @Id
     private Long id; 
     @Column(name = "Name")
     private String name; 

     ...
     List<Attachment> attachments; 
     ...
}


@Entity
@Table(name = "user_attachment")
public class UserAttachment {
    @Id
    @Column(name = "user_id");
    private Long userId;
    @Id 
    @Column(name = "attachment_id")
    private Long attachmentId
    ....
}
@Entity
@Table(name = "attachment")
public class Attachment {

    @Column(name = "id");
    private Long id;

    @Column(name = "original_name")
    private Long originalName
    ....
}

Возможно ли это? Или я должен изменить список пользователя, чтобы он стал списком User_Attachments, а затем user_attachments добавить соединение? По сути, JPA может «сгладить» мои объекты или мне нужно

Ответы [ 3 ]

1 голос
/ 22 апреля 2020

Возможно, вы захотите использовать отношения в своих моделях. Spring Data JPA занимается созданием таблиц соединения. Если вы go хотите указать сущности объединяемой таблицы, то, боюсь, вы не сможете использовать возможности Spring Data во многих местах.

Итак, вам необходимо создать следующие отношения:

  1. Пользователь - Вложение -> Один ко многим (при условии, что у одного пользователя много вложений, но у вложений один пользователь)
  2. Собака - Вложение -> Один ко многим (как описано выше) )

Для этого вам просто необходимо создать следующие модели: User, Dog, Attachment. Вы можете найти эту ссылку полезной для понимания.

Рабочий (пример) пример:

// @Entity and other annotations
public class Attachment {

    @Id
    @GeneratedValue
    private long id;

    @Column(nullable=false)
    private String url;

    // add all other fields here, like savedName, dates, whatever

    @ManyToOne
    @JoinColumn(name="attachment_id")
    private User user;
    @ManyToOne
    @JoinColumn(name="attachment_id")
    private Dog dog;

    // standard constructor, getter, setter
} 
// @Entity and other annotations
public class User {

    //...

    @OneToMany(mappedBy = "user")
    private Set<Attachment> attachments;

    //...

} 
// @Entity and other annotations
public class Dog {

    //...

    @OneToMany(mappedBy = "dog")
    private Set<Attachment> attachments;

    //...

}

Это создаст для вас двунаправленные отношения. Возможно, вы также захотите взглянуть на однонаправленные отношения, где не будет присутствовать сторона «многие к одному». Ура!

0 голосов
/ 16 апреля 2020

Если я понимаю, что вы пытаетесь сделать, вы можете использовать аннотацию JoinTable.

Определяет сопоставление ассоциаций. Он применяется к владельцу ассоциации. Таблица соединений обычно используется при отображении связей «многие ко многим» и однонаправленных связей «один ко многим». Он также может использоваться для сопоставления двунаправленных ассоциаций «многие к одному» или «один ко многим», однонаправленных связей «многие к одному» и связей «один к одному» (как двунаправленных, так и однонаправленных).

Когда таблица соединения используется при отображении отношения с встраиваемым классом на стороне-владельце отношения, а не объект встраиваемого класса, который содержит сущность, считается владельцем отношения.

Если аннотация JoinTable отсутствует, применяются значения по умолчанию для элементов аннотации. Предполагается, что именем таблицы соединений являются имена таблиц связанных первичных таблиц, соединенных вместе (сначала со стороной-владельцем) с использованием подчеркивания.

Таким образом, классы будут выглядеть как

Пользователь :

@Entity
//User is keyword in postgres and so cannot have table called "user"
@Table(name = "users")
public class User  {
    @Id
    @Column(name = "user_id")
    private Long id;
    @Column(name = "Name")
    private String name;
    @JoinTable(name = "user_attachment", joinColumns = @JoinColumn(name="user_id"),inverseJoinColumns = @JoinColumn(name ="attachment_id"))
    @OneToMany
    //Best to use sets since all elements must be unique for persistence reasons
    Set<Attachment> attachments;

    User(){
        //Ensure set is never null
        this.attachments = new HashSet<>();
    }

     ... Getters setters whatever

}

Приложение:

@Entity
@Table(name = "attachment")
public class Attachment {

    @Id
    @Column(name = "attachment_id")
    private Long id;

    @Column(name="original_name")
    String originalName;

    ... Getters setters whatever

}

Вам не нужно определять user_attachment, поскольку сопоставление выполняется с помощью @JoinColumn

0 голосов
/ 02 апреля 2020

Первый импорт lombok.

У вас есть несколько аннотаций ID в вашей сущности UserAttachment, уточните это и определите правильный идентификатор для таблицы, связанной с этой сущностью

Попробуйте структурировать ваш код следующим образом : Entity


@Component
@Entity
@Table(name = "user_attachment")
@ToString
@NoArgsConstructor
@Data
public class UserAttachmentEntity  {

    @Id
    @Getter
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "attachment_id")
    private Long attachmentId;


реализует ваш репозиторий

public interface UserAttachmentRepository extends JpaRepository<UserAttachmentEntity, Long> {

    List<UserAttachmentEntity  > findByAttachmentId(Long attachmentId);

}
...