gpt4 book ai didi

java - 注释 m :n relationship with helper class (2 foreign keys + additional attributes) with JPA 2. 0

转载 作者:行者123 更新时间:2023-12-04 05:50:37 25 4
gpt4 key购买 nike

我是 JPA 2.0 的新手,在注释 n:m 关系时遇到了麻烦,该关系使用外键类和描述关系的附加属性:

客户可以订阅多本杂志,每期Subscription正好为一个 Customer 创建和一个 Magazine ,另外节省订阅的持续时间。

这是我的带注释的类,我正在使用字段访问。我省略了一些样板代码,如构造函数、setter、getter(未注释)和方法 toString , equalshashCode .

@Entity
public class Customer {
@Id
@GeneratedValue
private Long id;
private String name;
@ManyToMany
private Set<Subscription> subscriptions;

// ..
}

@Entity
public class Magazine {
@Id
@GeneratedValue
private Long id;
private String name;

@ManyToMany
private Set<Subscription> subscriptions;

// ..
}

@Entity
public class Subscription {
private Date start;
private Date end;

@EmbeddedId
private SubscriptionId id;

// ..
}

@Embeddable
public class SubscriptionId implements Serializable {
@ManyToOne
private Customer customer;
@ManyToOne
private Magazine magazine;

// ..
}

我通过创建和保留一些对象来测试我的注释,如下所示:
public static void main(String[] args) {
EntityManagerFactory emf = Persistence
.createEntityManagerFactory("kiosk");
EntityManager em = emf.createEntityManager();

persist(em);

em.close();
emf.close();
}

private static void persist(EntityManager em) {
em.getTransaction().begin();

Magazine mag1 = new Magazine("mag1");
Magazine mag2 = new Magazine("mag2");

Customer cus1 = new Customer("cus1");
Customer cus2 = new Customer("cus2");
Customer cus3 = new Customer("cus3");

Subscription sub1 = new Subscription(cus1, mag1);
Subscription sub2 = new Subscription(cus2, mag1);
Subscription sub3 = new Subscription(cus2, mag2);
Subscription sub4 = new Subscription(cus3, mag2);

em.persist(mag1);
em.persist(mag2);

em.persist(cus1);
em.persist(cus2);
em.persist(cus3);

em.persist(sub1);
em.persist(sub2);
em.persist(sub3);
em.persist(sub4);

em.getTransaction().commit();
}

提供程序创建以下 MySQL 数据库:
mysql> show tables;
+-----------------------+
| Tables_in_kiosk |
+-----------------------+
| customer |
| customer_subscription |
| magazine |
| magazine_subscription |
| subscription |
+-----------------------+

只有三个表 customer , magazinesubscription有内容:
mysql> select * from customer;
+-------------+------+
| customer_id | name |
+-------------+------+
| 1 | cus1 |
| 2 | cus2 |
| 3 | cus3 |
+-------------+------+

mysql> select * from magazine;
+-------------+------+
| magazine_id | name |
+-------------+------+
| 1 | mag1 |
| 2 | mag2 |
+-------------+------+

mysql> select * from subscription;
+------+-------+-------------+-------------+
| end | start | magazine_id | customer_id |
+------+-------+-------------+-------------+
| NULL | NULL | 1 | 1 |
| NULL | NULL | 1 | 2 |
| NULL | NULL | 2 | 2 |
| NULL | NULL | 2 | 3 |
+------+-------+-------------+-------------+

如果我知道他们的 key ,我就可以阅读我的订阅。不过,我还没有尝试为客户或杂志阅读整套内容。
private static void find(EntityManager em) {
Magazine mag1 = em.find(Magazine.class, 1L);
Magazine mag2 = em.find(Magazine.class, 2L);

Customer cus1 = em.find(Customer.class, 1L);
Customer cus2 = em.find(Customer.class, 2L);
Customer cus3 = em.find(Customer.class, 3L);

Subscription sub1 = em.find(Subscription.class, new SubscriptionId(cus1, mag1));
Subscription sub2 = em.find(Subscription.class, new SubscriptionId(cus2, mag1));
Subscription sub3 = em.find(Subscription.class, new SubscriptionId(cus2, mag2));
Subscription sub4 = em.find(Subscription.class, new SubscriptionId(cus3, mag2));

System.out.println(mag1);
System.out.println(mag2);

System.out.println(cus1);
System.out.println(cus2);
System.out.println(cus3);

System.out.println(sub1);
System.out.println(sub2);
System.out.println(sub3);
System.out.println(sub4);
}

打印:
Magazine [id=1, name=mag1, subscriptions=null]
Magazine [id=2, name=mag2, subscriptions=null]
Customer [id=1, name=cus1, subscriptions=null]
Customer [id=2, name=cus2, subscriptions=null]
Customer [id=3, name=cus3, subscriptions=null]
Subscription [start=null, end=null, id=SubscriptionId [customer=1, magazine=1]]
Subscription [start=null, end=null, id=SubscriptionId [customer=2, magazine=1]]
Subscription [start=null, end=null, id=SubscriptionId [customer=2, magazine=2]]
Subscription [start=null, end=null, id=SubscriptionId [customer=3, magazine=2]]

两张表 customer_subscriptionmagazine_subscription保持空。但在我看来,它们甚至没有必要——其他 3 个表看起来和我想要的完全一样。所以我的问题是:

如何使用 JPA 2.0 正确建模此示例中使用的 m:n 关系,同时不创建多余的表,同时保留编写和读取杂志或客户的所有订阅的能力?

如果有人对代码感兴趣,我已将其上传到此处: http://goo.gl/qSc2e ;您需要一个名为“kiosk”的 MySQL 5 数据库,该数据库在本地主机上的端口 3306 上运行,root 密码为空。

最佳答案

您的模型实际上没有任何多对多关系。
CustomerSubscription是一对多。MagazineSubscription是一对多。

试试这个作为你的实体模型:

@Entity
public class Customer {

@Id
@GeneratedValue
private Long id;

private String name;

@OneToMany
private Set<Subscription> subscriptions;

// ..
}

@Entity
public class Magazine {
@Id
@GeneratedValue
private Long id;

private String name;

@OneToMany
private Set<Subscription> subscriptions;

// ..
}

@Entity
public class Subscription {

private Date start;

private Date end;

@EmbeddedId
private SubscriptionId id;

// ..
}

@Embeddable
public class SubscriptionId implements Serializable {

@ManyToOne
private Customer customer;

@ManyToOne
private Magazine magazine;

// ..
}

并且 Hibernate 不会生成冗余链接表。

关于java - 注释 m :n relationship with helper class (2 foreign keys + additional attributes) with JPA 2. 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10093241/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com