2015-12-10 3 views
0

У меня есть 2 объекта Клиент и Адрес, отношение - это адрес, который может принадлежать нескольким клиентам.JPA: Проблемы, сохраняющиеся в двух объектах, которые имеют отношение OneToMany

Ниже приведен список клиентов, так как вы можете видеть, что у него есть ссылка на адресный объект, в таблице основного клиента это идентификатор адреса. Я опустил геттеры и сеттеры, а также некоторые простые переменные.

@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)  

Но я получаю сообщение об ошибке, указывающее, что адрес_ид в таблице клиентов равен нулю. Я бы подумал, что JPA вставил новый адрес, а затем вставил нового клиента с столбцом идентификатора адреса, установленным на новый идентификатор адреса? Я не ошибаюсь? Или я допустил ошибку в сопоставлении или как я сохраняю сущности?

Еще один способ, которым я мог это сделать, это перенести адрес сначала, а затем сохранить клиента, но он предпочел бы сделать это в одном случае, если это возможно.

Ниже приведены основные таблицы.

//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; 

Спасибо.

ответ

1

Если вы хотите сохранить новый Address с Customer вам нужно добавить 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) 

Но это не очень удобный способ из-за адреса что-то вроде ссылки. Так что необычно обновлять адрес в ссылке, сохраняя каждого клиента.

+0

Спасибо, что это сработало. – JCS

+0

@JCS Добро пожаловать –

Смежные вопросы