我是新来的休眠者,学习文档保存持久对象
以下hibernate doc是一对多的人与电话的关系
const handleSaveToPC = jsonData => {
const fileData = JSON.stringify(jsonData);
const blob = new Blob([fileData], {type: "text/plain"});
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.download = 'filename.json';
link.href = url;
link.click();
}
我是坚持不懈的人,请添加一部手机以免出错
@Entity
@Table(name = "phone")
public class Phone {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "number")
private String number;
@ManyToOne(fetch = FetchType.LAZY)
private Person person;
//omit setter and getter
}
@Entity
@Table(name = "person")
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String username;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "person")
private List<Phone> phones = new ArrayList<>();
//omit getter and setter
}
这是坚持不懈的
@Test
public void say() {
Person person = new Person();
person.setUsername("aaaa");
Phone phone = new Phone();
phone.setNumber("111");
person.getPhones().add(phone);
personService.save(person);
}
更新服务代码,服务只是保存人
public class PersonDaoImpl implements PersonDao {
@PersistenceContext
private EntityManager entityManager;
@Override
public void save(Person person) {
entityManager.persist(person);
}
错误信息:
@Service(value = "personService")
public class PersonServiceImpl implements PersonService {
@Autowired
private PersonDao personDao;
@Transactional
@Override
public void save(Person person) {
personDao.save(person);
}
}
答案 0 :(得分:2)
添加@GeneratedValue
批注以指定两个实体的主键都将填充到代码之外。
@Entity
@Table(name = "phone")
public class Phone {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
@Column(name = "number")
private String number;
@JoinColumn("person_id")
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Person person;
//omit setter and getter
}
public class Person {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
private String username;
@OneToMany(mappedBy = "person")
private List<Phone> phones = new ArrayList<>();
//omit getter and setter
}
另外,由于没有从Person
到Phone
的级联配置,因此需要持久保存Phone
对象而不是Person
对象。如果您不能这样做,请将CascadeType
上的Person
切换为无,并将级联放置在Phone
上,如上所示。
您还应该在@JoinColumn
实体上添加Phone
注释,以便hibernate知道外键列。
答案 1 :(得分:1)
您错过了一些东西。您可以尝试一下。
人员实体
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String username;
@OneToMany(mappedBy = "person")
private List<Phone> phones = new ArrayList<>();
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public List<Phone> getPhones() {
return phones;
}
public void setPhones(List<Phone> phones) {
this.phones = phones;
}
//omit getter and setter
}
电话实体
@Entity
@Table(name = "phone")
public class Phone {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(name = "number")
private String number;
@ManyToOne(cascade = CascadeType.PERSIST)
private Person person;
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
//ommit setter and getter
}
电话道
public interface PhoneDao {
public Phone save(Phone phone);
}
PhoneDaoImpl
@Repository
public class PhoneDaoImpl implements PhoneDao {
@PersistenceContext
private EntityManager entityManager;
@Override
public Phone save(Phone phone) {
return entityManager.merge(phone);
}
}
PersonDaoImpl
@Repository
public class PersonDaoImpl implements PersonDao{
@PersistenceContext
private EntityManager entityManager;
@Override
public Person save(Person person) {
return entityManager.merge(person);
}
}
测试方法
@Test
@Transactional
@Commit
public void say()
{
Phone phone = new Phone();
phone.setNumber("jghjkhk");
Person person = new Person();
person.setUsername("7576");
phone.setPerson(person);
Phone pers = phoneDao.save(phone);
Assert.assertNotNull(pers);
}
立即尝试。它将起作用。
答案 2 :(得分:0)
我认为您需要设置person-> id的值,然后还使用getter方法将id传递给您的电话对象,而不是传递person对象
答案 3 :(得分:0)
通常人们已经使用代理键自动休眠设置实体的ID。
public class Person {
@Id @GeneratedValue // should pick an appropriate strategy here
private long id;
由于您没有,所以您必须添加它或自己设置它。
Person p = new Person();
p.setId(1); // hopefully unique
电话也一样。
答案 4 :(得分:0)
由于您的@Id上没有任何生成类型,并且id是主键,不能为null,因此您必须在id字段上设置id的值或具有@GeneratedValue注释,并将策略设置为Auto或身份。
您还可以生成自己的序列。
此外,您需要对Phone类进行相同的操作。