【问题标题】:How to setup JPA Entity classes?如何设置 JPA 实体类?
【发布时间】:2016-03-08 22:13:00
【问题描述】:

我正在努力设置我的 JPA 实体类以及哪些注释应该放在哪里

我有以下表格:

Table Customer {
    id: primary key,
    name
}

Table CustomerDimension {
    id: primary key, foreign key(Customer.id),
    detail
}

目前我有以下实体类:

public class Customer {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private long id;
    @Column(name = "name")
    private String name;
    @OneToOne
    private CustomerDimension customerDimension;
}

public class CustomerDimension {
    // ? what is meant to go here?
    private long id;
    @Column(name = "detail")
    private String detail;
}

CustomerDimension.id 上的注释是什么,以允许我插入具有新 CustomerDimension 的新客户?

CustomerDimension 是否也应该有对 Customer 的引用?

【问题讨论】:

  • 只需输入@Id,因为您的关系是单向的
  • @Ramanlfc - 这不是双向关系吗,我可以从 CustomerDimension -> Customer 去,反之亦然?
  • 你还需要在两个类上添加注解@Entity@Table
  • 第二类你也需要@GeneratedValue,你应该通过一些基础教程来查看示例
  • 您的映射与您的架构所需的完全相反

标签: java jpa


【解决方案1】:
Table Customer {
    id: primary key,
    name
}

Table CustomerDimension {
    id: primary key, 
    foreign key(Customer.id),
    detail
}

CustomerDimension 是拥有方。所以,@OneToOne 映射应该像

public class Customer {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private long id;
    @Column(name = "name")
    private String name;
}

public class CustomerDimension {
    @Id
    private long id;
    @Column(name = "detail")
    private String detail;

     @OneToOne
   private Customer customer;
}

【讨论】:

    【解决方案2】:

    你有以下问题:

    • Customer 和 CustomerDimension 需要注解@Entity
    • 在您的 DDL 中,表 CustomerDimensionCustomer 上有一个外键。因此,@OneToOne 关系应该在CustomerDimension 的一方声明。
    • 仍在 DDL 中,您的外键没有明确的名称。我假设它是customer_id 并用它来声明@JoinColumn(见下文)
    • @Column 注释仅在您需要列的名称与属性名称不同时才需要(但为了清楚起见,您可以保留它们)。

    这是我将如何映射它。

    @Entity
    @Table(name = "Customer") //Optional
    public class Customer {
    
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      private long id;
    
      @Column(name = "name") //Optional
      private String name;
    }
    

    对于CustomerDimension

    @Entity
    @Table(name = "CustomerDimension") //Optional
    public class CustomerDimension {
    
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      private long id;
    
      @Column(name = "detail") //Optional
      private String detail;
    
      @OneToOne
      @JoinColumn(name = "customer_id") //NOT optional
      private Customer customer
    }
    

    编辑(回答您的评论):

    如果你真的想让你的 FK 成为主键,你可以这样做:

    @Entity
    @Table(name = "CustomerDimension") //Optional
    public class CustomerDimension {
    
      @Column(name = "detail") //Optional
      private String detail;
    
      @Id
      @OneToOne
      @JoinColumn(name = "id") //NOT optional
      private Customer customer
    }
    

    我仍然想知道您为什么不将所有信息放在同一张表中。它会为您节省一个 SQL 连接。

    【讨论】:

    • 我觉得我可能给表定义错误。 Customer 是根对象(如果你喜欢,上下文/主题)。 CustomerDimension 只是Customer 的额外信息,所以我期待从Customer 实体到达CustomerDimension 实体。此外,不会生成CustomerDimension.id。它应该与引用的Customer.id 相同。 Customer是生成id的实体
    • @Cheetah 那么您可以将 FK 定义为 PK,但这似乎是一个奇怪的用例。编辑了答案。
    • 它是一个单独的表,因为 CustomerDimension 记录很大,并不总是需要。
    【解决方案3】:

    这里有一个OneToMany 与外键而不是连接表的双向关系。供应商似乎更喜欢连接表,但没关系。

    因此,您在Customer 中有一个CustomerDimensions 列表(或集合),但设置了mappedBy 值。

    public class Customer {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "id")
        private long id;
        @Column(name = "name")
        private String name;
    
        @OneToMany(mappedBy="customer")
        List<CustomerDimensions> dimensions;
    }
    

    public class CustomerDimension {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "id")
        private long id;
        @Column(name = "detail")
        private String detail;
    
        @ManyToOne
        Customer customer;
    
    }
    

    Customers 有一组维度是很自然的。通过bidirectional 映射,如果您有维度,则可以轻松查找客户(只需引用客户字段)

    编辑:由于CustomerDimension 表具有Customer id 引用,您可以为一个Customer 选择多个CustomerDimensions,因此OneToMany 关系。为了设置CustomerDimension.customer_id 字段,只需将CustomerDimension 放入Customers 维度列表中。

    【讨论】:

    • 其实是一对一的映射,所以一个Customer只有一个维度。但它是双向的,但我不明白的是CustomerDimension.id上没有注释......这个值是如何填充的?
    • 是什么让您认为它是 OnToOne?您需要 CustomerDimension.id 上的典型 ID 注释。我把它们排除在外是因为你这样做了。查看修改。
    猜你喜欢
    • 2011-02-25
    • 2018-01-03
    • 2017-04-16
    • 2023-03-28
    • 1970-01-01
    • 2019-08-19
    • 2016-05-05
    • 2022-10-17
    • 1970-01-01
    相关资源
    最近更新 更多