繁体   English   中英

JPA:持续存在两个具有OneToMany关系的实体的问题

[英]JPA: Issues persisting 2 entities which have a OneToMany relation

我有2个实体Customer和Address,关系是一个地址可以属于多个客户。

下面是客户类,您可以看到它具有对地址对象的引用,在基础客户表中,它是地址的ID。 我省略了getter和setter以及一些简单的变量。

@Entity
@Table(name = "customer")
public class Customer implements Serializable  {

@Id
@GeneratedValue
@Column(name = "customer_id")
private int customerId;
@ManyToOne
@JoinColumn(name = "store_id")
private Store store;
@ManyToOne
@JoinColumn(name = "address_id")
private Address address;
........
}

下面是地址类。

//Address Class
@Entity
@Table(name = "address")
public class Address implements Serializable {

@Id
@GeneratedValue
@Column(name = "address_id")
private int addressId;
@JoinColumn(name = "city_id")
@ManyToOne
private City city;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "address")
@JsonIgnore
List<Customer> customers;
 ......
}

我试图在一个电话中保留新客户和新地址,以像下面这样保留。 我省略了我设置的一些变量。

Customer cus = new Customer();
Address addr= new Address();
........
cus.setAddress(addr)
List<Customer> cusList= new ArrayList<>();
cusList.add(cus);
addr.setCustomers(cusList);
entityManager.persist(cus)    

但是我收到一条错误消息,说客户表中的address_id为null。 我以为JPA会插入新地址,然后插入新客户,并将地址ID列设置为新地址ID? 我的想法错了吗? 还是我在映射中犯了一个错误,或者我是如何持久化实体的?

我可以执行此操作的另一种方法是先持久保存地址,然后持久保存客户,但如果可能的话,希望在单个持久保存中执行。

下面是基础表。

//Customer Table
CREATE TABLE `customer` (
   `customer_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
   `store_id` tinyint(3) unsigned NOT NULL,
   `first_name` varchar(45) NOT NULL,
   `last_name` varchar(45) NOT NULL,
   `email` varchar(50) DEFAULT NULL,
   `address_id` smallint(5) unsigned NOT NULL,
   `active` tinyint(1) NOT NULL DEFAULT '1',
   `create_date` datetime NOT NULL,
   `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE      CURRENT_TIMESTAMP,
   PRIMARY KEY (`customer_id`),
   KEY `idx_fk_store_id` (`store_id`),
   KEY `idx_fk_address_id` (`address_id`),
   KEY `idx_last_name` (`last_name`),
   CONSTRAINT `fk_customer_address` FOREIGN KEY (`address_id`) REFERENCES    `address` (`address_id`) ON UPDATE CASCADE,
   CONSTRAINT `fk_customer_store` FOREIGN KEY (`store_id`) REFERENCES  `store` (`store_id`) ON UPDATE CASCADE
  ) ENGINE=InnoDB AUTO_INCREMENT=608 DEFAULT CHARSET=utf8;

/Address Table

CREATE TABLE `address` (
  `address_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
  `address` varchar(50) NOT NULL,
  `address2` varchar(50) DEFAULT NULL,
  `district` varchar(20) NOT NULL,
  `city_id` smallint(5) unsigned NOT NULL,
  `postal_code` varchar(10) DEFAULT NULL,
  `phone` varchar(20) NOT NULL,
  `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE    CURRENT_TIMESTAMP,
  PRIMARY KEY (`address_id`),
  KEY `idx_fk_city_id` (`city_id`),
  CONSTRAINT `fk_address_city` FOREIGN KEY (`city_id`) REFERENCES `city` (`city_id`) ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=619 DEFAULT CHARSET=utf8;

谢谢。

如果要与Customer保存新Address ,则需要添加CascadeType.ALL

@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "address_id")
private Address address;

并通过这种方式保存所有内容(您无需将客户添加到地址列表中,因为客户仅通过外键address_id引用地址即可)

Customer cus = new Customer();
Address addr = new Address();
cus.setAddress(addr)
entityManager.persist(cus)

但这不是一种非常方便的方法,因为地址类似于引用。 因此,通过保存每个客户来更新参考地址是不寻常的。

暂无
暂无

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

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