@OneToMany и составные первичные ключи?

В Postgres 9.4 или новее это, вероятно, простейшее и быстрое :

SELECT c.*
FROM   comments c
JOIN   unnest('{1,3,2,4}'::int[]) WITH ORDINALITY t(id, ord) USING (id)
ORDER  BY t.ord;
  • Используя новый WITH ORDINALITY что @a_horse уже упоминается .
  • Нам не нужен подзапрос, мы можем использовать функцию возвращаемого набора, такую ​​как таблица.
  • Строковый литерал

Подробное объяснение:

29
задан Pascal Thivent 14 April 2010 в 00:31
поделиться

4 ответа

После долгих экспериментов и разочарований я в конце концов решил, что не могу делать именно то, что хочу.

В конечном счете, я пошел дальше и дал дочернему объекту свой собственный синтетический ключ и позволил Hibernate управлять им. Это не идеально, так как ключ почти такой же большой, как и остальные данные, но он работает.

2
ответ дан Kris Pruden 28 November 2019 в 02:03
поделиться

Вы должны включить ссылку ParentObject только в ChildObject.Pk, а не сопоставлять parent и parentId по отдельности:

(методы получения, установки, атрибуты Hibernate не связаны с проблемой и ключевые слова доступа к элементам опущены)

class ChildObject { 
    @Embeddable
    static class Pk {
        @ManyToOne...
        @JoinColumn(name="parentId")
        ParentObject parent;

        @Column...
        String name...
        ...
    }

    @EmbeddedId
    Pk id;
}

В ParentObject вы просто помещаете @OneToMany(mappedBy="id.parent"), и это работает.

6
ответ дан Tomáš Záluský 28 November 2019 в 02:03
поделиться

Книга Маннинга Сохранение Java с Hibernate содержит пример, описывающий, как это сделать, в Разделе 7.2. К счастью, даже если вы не являетесь владельцем книги, вы можете увидеть пример этого исходного кода, загрузив JPA-версию примера проекта Caveat Emptor (прямая ссылка здесь ) и изучение классов Category и CategoryizedItem в пакете uction.model .

Я также резюмирую основные аннотации ниже. Дай мне знать, если это все еще не разрешено.

ParentObject:

@Entity
public class ParentObject {
   @Id @GeneratedValue
   @Column(name = "parentId", nullable=false, updatable=false)
   private Long id;

   @OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
   @IndexColumn(name = "pos", base=0)
   private List<ChildObject> attrs;

   public Long getId () { return id; }
   public List<ChildObject> getAttrs () { return attrs; }
}

ChildObject:

@Entity
public class ChildObject {
   @Embeddable
   public static class Pk implements Serializable {
       @Column(name = "parentId", nullable=false, updatable=false)
       private Long objectId;

       @Column(nullable=false, updatable=false)
       private String name;

       @Column(nullable=false, updatable=false)
       private int pos;
       ...
   }

   @EmbeddedId
   private Pk id;

   @ManyToOne
   @JoinColumn(name="parentId", insertable = false, updatable = false)
   @org.hibernate.annotations.ForeignKey(name = "FK_CHILD_OBJECT_PARENTID")
   private ParentObject parent;

   public Pk getId () { return id; }
   public ParentObject getParent () { return parent; }
}
16
ответ дан 28 November 2019 в 02:03
поделиться

Во-первых, в ParentObject "исправьте" атрибут mappedBy, который должен быть установлен в "parent". Также (но это, возможно, опечатка) добавьте аннотацию @Id:

@Entity
public class ParentObject {
    @Id
    @GeneratedValue
    private String id;

    @OneToMany(mappedBy="parent", fetch=FetchType.EAGER)
    @IndexColumn(name = "pos", base=0)
    private List<ObjectChild> attrs;

    // getters/setters
}

Затем в ObjectChild добавьте атрибут name к objectId в составном ключе:

@Entity
public class ObjectChild {
    @Embeddable
    public static class Pk implements Serializable {
        @Column(name = "parentId", nullable = false, updatable = false)
        private String objectId;

        @Column(nullable = false, updatable = false)
        private String name;

        @Column(nullable = false, updatable = false)
        private int pos;
    }

    @EmbeddedId
    private Pk pk;

    @ManyToOne
    @JoinColumn(name = "parentId", insertable = false, updatable = false)
    private ParentObject parent;

    // getters/setters

}

И также добавьте insertable = false, updatable = false к @JoinColumn, потому что мы повторяем колонку parentId в отображении этой сущности.

С этими изменениями персистенция и чтение сущностей работает нормально (проверено на Derby).

3
ответ дан 28 November 2019 в 02:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: