复合主键 Hibernate 和 Java 实现

发布于 2024-10-20 23:37:15 字数 4591 浏览 5 评论 0原文

我定义了一个非常简单的数据库,如下所示:

MySql Simple Database

我正在使用 hibernate 插件来生成不同的数据库类,包括客户和订单之间的一对多关系。我将这种关系作为一种识别关系,因为如果没有链接到客户,订单就不会存在。

我有以下三个课程:

=>类客户

private int idCustomer;
private String name;
private Set<Order> orders = new HashSet<Order>(0);

public Customer() {
}

public Customer(int idCustomer) {
    this.idCustomer = idCustomer;
}

public Customer(int idCustomer, String name, Set<Order> orders) {
    this.idCustomer = idCustomer;
    this.name = name;
    this.orders = orders;
}

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "idCustomer", unique = true, nullable = false)
public int getIdCustomer() {
    return this.idCustomer;
}

public void setIdCustomer(int idCustomer) {
    this.idCustomer = idCustomer;
}

@Column(name = "name", length = 45)
public String getName() {
    return this.name;
}

public void setName(String name) {
    this.name = name;
}

@OneToMany(fetch = FetchType.LAZY, mappedBy = "customer")
public Set<Order> getOrders() {
    return this.orders;
}

public void setOrders(Set<Order> orders) {
    this.orders = orders;
}

=>班级顺序:

private OrderId id;
private Customer customer;
private String quantity;
private Float price;

public Order() {
}

public Order(OrderId id, Customer customer) {
    this.id = id;
    this.customer = customer;
}

public Order(OrderId id, Customer customer, String quantity, Float price) {
    this.id = id;
    this.customer = customer;
    this.quantity = quantity;
    this.price = price;
}

@EmbeddedId
@AttributeOverrides({
        @AttributeOverride(name = "idOrder", column = @Column(name = "idOrder", nullable = false)),
        @AttributeOverride(name = "customerIdCustomer", column = @Column(name = "Customer_idCustomer", nullable = false)) })
public OrderId getId() {
    return this.id;
}

public void setId(OrderId id) {
    this.id = id;
}

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "Customer_idCustomer", nullable = false, insertable = false, updatable = false)
public Customer getCustomer() {
    return this.customer;
}

public void setCustomer(Customer customer) {
    this.customer = customer;
}

@Column(name = "quantity", length = 45)
public String getQuantity() {
    return this.quantity;
}

public void setQuantity(String quantity) {
    this.quantity = quantity;
}

@Column(name = "price", precision = 12, scale = 0)
public Float getPrice() {
    return this.price;
}

public void setPrice(Float price) {
    this.price = price;
}

=> Class OrderId

private int idOrder;
private int customerIdCustomer;

public OrderId() {
}

public OrderId(int idOrder, int customerIdCustomer) {
    this.idOrder = idOrder;
    this.customerIdCustomer = customerIdCustomer;
}

@Column(name = "idOrder", nullable = false)
public int getIdOrder() {
    return this.idOrder;
}

public void setIdOrder(int idOrder) {
    this.idOrder = idOrder;
}

@Column(name = "Customer_idCustomer", nullable = false)
public int getCustomerIdCustomer() {
    return this.customerIdCustomer;
}

public void setCustomerIdCustomer(int customerIdCustomer) {
    this.customerIdCustomer = customerIdCustomer;
}

public boolean equals(Object other) {
    if ((this == other))
        return true;
    if ((other == null))
        return false;
    if (!(other instanceof OrderId))
        return false;
    OrderId castOther = (OrderId) other;

    return (this.getIdOrder() == castOther.getIdOrder())
            && (this.getCustomerIdCustomer() == castOther
                    .getCustomerIdCustomer());
}

public int hashCode() {
    int result = 17;

    result = 37 * result + this.getIdOrder();
    result = 37 * result + this.getCustomerIdCustomer();
    return result;
}

然后我有我的主类:

public static void main(String[] args) {
    Customer customer = new Customer();
    customer.setName("John Doe");
    CustomerDAO.save(customer);

    Order order = new Order();
    order.setQuantity(10);
    order.setPrice(100);
    order.setCustomer(customer);

    OrderDAO.save(order);

}

请注意,我的 DAO 对象没有做任何花哨的事情...只是获取会话的常用 HibernateUtil 实现并最终调用“保存”方法。我的问题如下。我以前从未处理过复合键...请提前原谅我的愚蠢问题。我不想手动处理不同的 id 和主键。对于 Cutomer 类,这不是问题,因为我设置了一个策略,在保存到数据库时会自动创建 id。对于 Order 类,我也不想处理这个问题。但由于密钥是复合的,Hibernate 在尝试将此对象保存在数据库中时会生成一个identifierGenerationExeption...我想要的是以下 =>自动生成的订单 ID,因为我在订单对象中设置了客户,所以我希望 Hibernate 将客户 ID 链接到组合键中的 ID...执行此操作的正确方法是什么?

谢谢

I have defined a very simple database as follow :

MySql Simple Database

I'm using the hibernate plug-in to generate the different classes, including the one-to-many relationship between customer and order. i made this relationship as an identifying relationship as an order could not exist if not linked to a customer.

I have the three following classes :

=> Class Customer

private int idCustomer;
private String name;
private Set<Order> orders = new HashSet<Order>(0);

public Customer() {
}

public Customer(int idCustomer) {
    this.idCustomer = idCustomer;
}

public Customer(int idCustomer, String name, Set<Order> orders) {
    this.idCustomer = idCustomer;
    this.name = name;
    this.orders = orders;
}

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "idCustomer", unique = true, nullable = false)
public int getIdCustomer() {
    return this.idCustomer;
}

public void setIdCustomer(int idCustomer) {
    this.idCustomer = idCustomer;
}

@Column(name = "name", length = 45)
public String getName() {
    return this.name;
}

public void setName(String name) {
    this.name = name;
}

@OneToMany(fetch = FetchType.LAZY, mappedBy = "customer")
public Set<Order> getOrders() {
    return this.orders;
}

public void setOrders(Set<Order> orders) {
    this.orders = orders;
}

=> Class Order :

private OrderId id;
private Customer customer;
private String quantity;
private Float price;

public Order() {
}

public Order(OrderId id, Customer customer) {
    this.id = id;
    this.customer = customer;
}

public Order(OrderId id, Customer customer, String quantity, Float price) {
    this.id = id;
    this.customer = customer;
    this.quantity = quantity;
    this.price = price;
}

@EmbeddedId
@AttributeOverrides({
        @AttributeOverride(name = "idOrder", column = @Column(name = "idOrder", nullable = false)),
        @AttributeOverride(name = "customerIdCustomer", column = @Column(name = "Customer_idCustomer", nullable = false)) })
public OrderId getId() {
    return this.id;
}

public void setId(OrderId id) {
    this.id = id;
}

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "Customer_idCustomer", nullable = false, insertable = false, updatable = false)
public Customer getCustomer() {
    return this.customer;
}

public void setCustomer(Customer customer) {
    this.customer = customer;
}

@Column(name = "quantity", length = 45)
public String getQuantity() {
    return this.quantity;
}

public void setQuantity(String quantity) {
    this.quantity = quantity;
}

@Column(name = "price", precision = 12, scale = 0)
public Float getPrice() {
    return this.price;
}

public void setPrice(Float price) {
    this.price = price;
}

=> Class OrderId

private int idOrder;
private int customerIdCustomer;

public OrderId() {
}

public OrderId(int idOrder, int customerIdCustomer) {
    this.idOrder = idOrder;
    this.customerIdCustomer = customerIdCustomer;
}

@Column(name = "idOrder", nullable = false)
public int getIdOrder() {
    return this.idOrder;
}

public void setIdOrder(int idOrder) {
    this.idOrder = idOrder;
}

@Column(name = "Customer_idCustomer", nullable = false)
public int getCustomerIdCustomer() {
    return this.customerIdCustomer;
}

public void setCustomerIdCustomer(int customerIdCustomer) {
    this.customerIdCustomer = customerIdCustomer;
}

public boolean equals(Object other) {
    if ((this == other))
        return true;
    if ((other == null))
        return false;
    if (!(other instanceof OrderId))
        return false;
    OrderId castOther = (OrderId) other;

    return (this.getIdOrder() == castOther.getIdOrder())
            && (this.getCustomerIdCustomer() == castOther
                    .getCustomerIdCustomer());
}

public int hashCode() {
    int result = 17;

    result = 37 * result + this.getIdOrder();
    result = 37 * result + this.getCustomerIdCustomer();
    return result;
}

I then have my main class :

public static void main(String[] args) {
    Customer customer = new Customer();
    customer.setName("John Doe");
    CustomerDAO.save(customer);

    Order order = new Order();
    order.setQuantity(10);
    order.setPrice(100);
    order.setCustomer(customer);

    OrderDAO.save(order);

}

Please note that my DAO objects are doing nothing fancy... Just the usual HibernateUtil implementation of getting the session and finally call the 'save' method. My Problem is the following. I have never dealt before with composite key... Excuse me for my stupid question in advance. I don't want to deal manually with the different ids and primary keys. For the Cutomer class, it is not a problem since I set up a strategy that will automatically create the id when saving in database. For the Order class, I don't want to deal with that as well. But since the key is composite, Hibernate generates an identifierGenerationExeption when trying to save this object in DB... What I would have liked is the following => an Order id generated automatically and since I setup the customer in the order Object, I would have expect hibernate to link the customer id to the one in the composite key... What is the correct way of doing this thing ?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

橘虞初梦 2024-10-27 23:37:15

为什么要在 Order 实体的主键中包含客户 ID 外键?它的主键应该是idOrderCustomer_idCustomer 应该是外键,并且不应该是订单 ID 的一部分。

Why do you include the customer ID foreign key in the primary key of your Order entity? Its primary key should be idOrder. Customer_idCustomer should be a foreign key, and should not be part of the ID of Order.

冰葑 2024-10-27 23:37:15

不鼓励使用复合键,并且仅应在被迫时使用(例如:遗留数据库)。我认为您应该将订单中的 Customer_id 设置为 not null。订单有一个简单、常规的 ID (idOrder),一切都应该很简单。

Using composite keys is discouraged and should only be used when forced to do it (say: legacy database). I think that you just should make the Customer_id in the Order not null. There is a simple, regular id for the order (idOrder) and everything should be straight forward.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文