简体   繁体   English

休眠-映射属性OneToMany。 (如OrderLine)不关联

[英]Hibernate - mapping an attribute OneToMany. (like OrderLine) Not association

I'm strugling with JPA. 我在与JPA斗争。 I tried several things but I can't figure out the right way to put the annotations. 我尝试了几种方法,但是找不到正确的注释方法。 What is want is like an Order/OrderLine relationship. 所需的就像一个Order / OrderLine关系。

Thus: 从而:

  • Order( PK=orderId, fields=[...]) 订单(PK = orderId,字段= [...])
  • OrderLine (Pk1=orderId,Pk2=orderLineId, fields=[...]) OrderLine(Pk1 = orderId,Pk2 = orderLineId,字段= [...])

Obviously, OrderLine.orderId refers to the 'Order' table. 显然,OrderLine.orderId是指“订单”表。

What I functionally want to do is at least: 我在功能上想要做的至少是:

  • retrieve the Order with and without all orderlines. 检索包含和不包含所有订单行的订单。 It should have a Set 它应该有一套
  • retrieve an orderline by full PK, but without the associated Order. 通过完整PK检索订单行,但没有关联的订单。
  • retrieve a list of orderlines by orderId. 通过orderId检索订单行列表。

I only want these 2 tables and classes. 我只想要这两个表和类。 nothing more nothing less. 仅此而已。 I tried several things. 我尝试了几件事。 Can anybody help me out with putting in the right annotations and members on these two classes? 有人可以帮我把正确的注释和成员放在这两个类上吗?

Edit: what i've done so far. 编辑:到目前为止我做了什么。 Note that in this real example User=Order and UserRun=OrderLine. 请注意,在此实际示例中,User = Order和UserRun = OrderLine。 So, i am not interested in a seperate 'Run'-entity. 因此,我对单独的“运行”实体不感兴趣。 Merely a UserRun as described by the Orderline. 只是按照订单行的描述运行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 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;
    }

}

This created a userruns/orderline table with the PK in the wrong way: create table user_runs (run_uuid varchar(255) not null, username varchar(255) not null, primary key (run_uuid, username)) 这用错误的方式用PK创建了一个用户运行/订单表:创建表user_runs(run_uuid varchar(255)不为空,用户名varchar(255)不为空,主键(run_uuid,用户名))

  1. I want the primary key in reverse. 我想要反向的主键。
  2. I want username as FK to User 我想将用户名作为FK发送给用户
  3. I want a Set in my User-class. 我想要在用户类中设置一个。

When I do the following in my User-class: 当我在用户类中执行以下操作时:

@OneToMany
private Set<UserRun> userRuns;

It will create a create table user_user_runs (user_username varchar(255) not null, user_runs_run_uuid varchar(255) not null, user_runs_username varchar(255) not null, primary key (user_username, user_runs_run_uuid, user_runs_username)) And that's something I definitely don't want! 它将创建一个创建表user_user_runs(user_username varchar(255)不为空,user_runs_run_uuid varchar(255)不为空,user_runs_username varchar(255)不为空,主键(user_username,user_runs_run_uuid,user_runs_username))想! Once again, I don't want a Run-object (same as nobody's interested in a Line-class, from OrderLine) 再一次,我不需要运行对象(就像OrderLine中的Line类一样,没人对它感兴趣)

I think I figured it out. 我想我知道了。

The UserRun/Orderline class: 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 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;
    }

}

In the userclass: 在用户类中:

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

Unfortunately, there are 2 downsides: 不幸的是,有两个缺点:

  1. I see that there are 2 queries executed instead of a Join on username. 我看到执行了2个查询,而不是用户名上的Join。 One to retrieve user, and 1 to retrieve the Set... 一个用于检索用户,一个用于检索Set ...

  2. I needed to alter variablenames of the PK (compound/Embeddable). 我需要更改PK(compound / Embeddable)的变量名。 It seems there is no clean way to define the PK order. 似乎没有干净的方法来定义PK顺序。 (Seriously?). (严重吗?)。 Fortunately, the variable name is private, and not exposed by getter. 幸运的是,变量名是私有的,不会被getter公开。

If anybody knows a cleaner way for these 2 issues. 如果有人知道这两个问题的更清洁方法。 Let me know! 让我知道!

I think what you have to do is the following: 我认为您需要执行以下操作:

  • Because the primary key is compound key you need an ID class, as you already did: 因为主键是复合键,所以您需要一个ID类,就像您已经做的那样:

     @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 } 
  • Implement OrderLine entity 实施OrderLine实体

     @Entity public class OrderLine { @EmbededId private OrderLinePK id; @Mapsid("orderID") @ManyToOne @JoinColumn(name = "ORDER_ID", referencedColumn="ID") private Order order; // getters + setters .... } 
  • And the Order entity: 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 .... } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM