2016-12-25 2 views
0

Я борюсь с JPA. Я пробовал несколько вещей, но я не могу понять, как правильно разместить аннотации. Что такое желание, как отношение Order/OrderLine.Hibernate - отображение атрибута OneToMany. (например, OrderLine) Не ассоциация

Таким образом:

  • заказа (PK = OrderId, поля = [...])
  • OrderLine (Pk1 = OrderId, pk2 = orderLineId, поля = [...])

Очевидно, что OrderLine.orderId относится к таблице «Заказ».

Что функционально нужно сделать, это по крайней мере:

  • получить орден с и без всех OrderLines. Он должен иметь набор
  • получить строку заказа полным ПК, но без соответствующего заказа.
  • получить список ордеров на заказ.

Мне нужны только эти 2 таблицы и классы. ни больше ни меньше. Я пробовал несколько вещей. Может ли кто-нибудь помочь мне с введением правильных аннотаций и членов в этих двух классах?

Редактировать: что я сделал до сих пор. Обратите внимание, что в этом реальном примере User = Order и UserRun = OrderLine. Поэтому меня не интересует отдельный «Run» -объект. Просто UserRun, как описано в Orderline.

@Entity 
@Table(name = "user_runs") 
public class UserRun { 

    @EmbeddedId 
    private UserRunKey id; 

    public UserRun(){}; 

    public UserRun(String userName, String runUuid) { 
     this.id = new UserRunKey(userName, runUuid); 
    } 

    public String getUserName() { 
     return this.id.getUserName(); 
    } 
    public String getRunUuid() { 
     return this.id.getRunUuid(); 
    } 
} 

@Embeddable 
class UserRunKey implements Serializable { 

    @Column(name = "username") 
    private String userName; 

    @Column(name = "run_uuid") 
    private String runUuid; 

    public UserRunKey(){}; 

    public UserRunKey(String userName, String runUuid) { 
     this.runUuid = runUuid; 
     this.userName = userName; 
    } 

    public String getUserName() { 
     return userName; 
    } 

    public String getRunUuid() { 
     return runUuid; 
    } 

} 

Это создало таблицу userruns/OrderLine с ПК в неправильном направлении: создать таблицу user_runs (run_uuid VARCHAR (255) NOT NULL, имя пользователя VARCHAR (255) NOT NULL, первичный ключ (run_uuid, имя пользователя))

  1. Я хочу, чтобы первичный ключ в обратном порядке.
  2. Я хочу, чтобы имя пользователя как FK для пользователя
  3. Я хочу набор в моем пользовательском классе.

Когда я делаю следующее в моем User-класс:

@OneToMany 
private Set<UserRun> userRuns; 

Это создаст создать таблицу user_user_runs (user_username VARCHAR (255) NOT NULL, user_runs_run_uuid VARCHAR (255) NOT NULL, user_runs_username varchar (255) не null, первичный ключ (user_username, user_runs_run_uuid, user_runs_username)) И это то, что я определенно не хочу! Еще раз, я не хочу Run-object (так же, как никто не интересуется линейным классом, из OrderLine)

+1

Вы должны отправить то, что вы делали до сих пор и объяснить вашу проблему с этим. – davidxxx

+0

отредактировал исходное сообщение. Хотя, я думаю, это делает вопрос более неясным. В основном это должно быть так: я хочу 2 класса: Order, OrderLine. Мне также нужны 2 таблицы: Order (pk = orderId), OrderLine (pk = (orderId, orderLineId)). Как я могу сделать такой простой пример с аннотациями JPA? –

+0

Все было бы намного проще, если бы runUuid (который кажется уникальным с учетом его имени и, следовательно, достаточен для уникальной идентификации UserRun), был основным ключом объекта. Тогда у вас будет простая стандартная ассоциация OneToMany, отображаемая столбцом объединения. –

ответ

0

Думаю, я это понял.

Класс UserRun/строки заказа:

@Entity 
@Table(name = "user_runs") 
public class UserRun { 

    @EmbeddedId 
    private UserRunKey id; 

    public UserRun(){}; 

    public UserRun(String userName, String runUuid) { 
     this.id = new UserRunKey(userName, runUuid); 
    } 

    public String getUserName() { 
     return this.id.getUserName(); 
    } 
    public String getRunUuid() { 
     return this.id.getRunUuid(); 
    } 
} 

@Embeddable 
class UserRunKey implements Serializable { 

    @Column(name = "username") 
    private String userName; 

    @Column(name = "run_uuid") 
    private String zrunUuid; //starts with a z, so the PK will be pk(username,run_uuid). Apparently, order in PK is determined from the variable names (alphabetic order).... 

    public UserRunKey(){}; 

    public UserRunKey(String userName, String zrunUuid) { 
     this.zrunUuid = zrunUuid; 
     this.userName = userName; 
    } 

    public String getUserName() { 
     return userName; 
    } 

    public String getRunUuid() { 
     return zrunUuid; 
    } 

} 

В Класс_пользователей:

@OneToMany(mappedBy = "id.userName", fetch = FetchType.LAZY, cascade = CascadeType.ALL) 
private Set<UserRun> userRuns; 

К сожалению, есть 2 недостатки:

  1. Я вижу, что есть 2 запросы выполняются вместо имени Присоединиться к имени пользователя. Один для извлечения пользователя и 1 для извлечения Set ...

  2. Мне нужно было изменить variablenames PK (составной/встраиваемый). Кажется, нет никакого чистого способа определить порядок PK. (Шутки в сторону?). К счастью, имя переменной является приватным и не отображается с помощью getter.

Если кто-то знает более чистый способ для этих 2 вопросов. Дай мне знать!

0

Я думаю, что вы должны сделать, это следующее:

  • Поскольку первичный ключ является составным ключом вам нужен идентификатор класса, как вы уже сделали:

    @Embeddable 
    class OrderLinePK implements Serializable { 
        // you can use physical mapping annotations such as @Column here 
        @Column(name="...") 
        private Integer orderLineID; 
    
        // This is foreign key and the physical mapping should be done 
        // on the entity, and not here 
        private Integer orderID; 
    
        public OrderLinePK(){} 
    
        // getters + setters 
        // orverride equals() and hashCode() methods 
    } 
    
  • Реализовать OrderLine юридическое лицо

    @Entity 
    public class OrderLine { 
        @EmbededId private OrderLinePK id; 
    
        @Mapsid("orderID") 
        @ManyToOne 
        @JoinColumn(name = "ORDER_ID", referencedColumn="ID") 
        private Order order; 
    
        // getters + setters .... 
    
    } 
    
  • И Order лицо:

    @Entity 
    public class Order { 
        @Id 
        private Integer id; 
    
        @OneToMany(fetch = FetchType.LAZY) // actually default by 1-to-n 
        private Coolection<OrderLine> orderLines; 
    
        // getters + setters .... 
    
    } 
    
Смежные вопросы