最近,我正在从事一个冬眠项目,我已经添加了少量实体豆,当我执行时,我获得了例外堆积痕迹。
1Initial SessionFactory creation failed.org.hibernate.AnnotationException: No identifier specified for entity: com.journaldev.hibernate.model.Address
2org.hibernate.AnnotationException: No identifier specified for entity: com.journaldev.hibernate.model.Address
3 at org.hibernate.cfg.InheritanceState.determineDefaultAccessType(InheritanceState.java:277)
4 at org.hibernate.cfg.InheritanceState.getElementsToProcess(InheritanceState.java:224)
5 at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:775)
6 at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3788)
7 at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3742)
8 at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1410)
9 at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1844)
10 at com.journaldev.hibernate.util.HibernateUtil.buildSessionFactory(HibernateUtil.java:22)
11 at com.journaldev.hibernate.util.HibernateUtil.getSessionFactory(HibernateUtil.java:34)
12 at com.journaldev.hibernate.main.HibernateExample.main(HibernateExample.java:15)
13Exception in thread "main" java.lang.ExceptionInInitializerError
14 at com.journaldev.hibernate.util.HibernateUtil.buildSessionFactory(HibernateUtil.java:29)
15 at com.journaldev.hibernate.util.HibernateUtil.getSessionFactory(HibernateUtil.java:34)
16 at com.journaldev.hibernate.main.HibernateExample.main(HibernateExample.java:15)
问题出现了,因为我忘了在我的实体棒中指定主键,我的棒被定义为; 'Address.java'
1package com.journaldev.hibernate.model;
2
3import javax.persistence.Column;
4import javax.persistence.Entity;
5import javax.persistence.GeneratedValue;
6import javax.persistence.Id;
7import javax.persistence.OneToOne;
8import javax.persistence.PrimaryKeyJoinColumn;
9import javax.persistence.Table;
10
11import org.hibernate.annotations.GenericGenerator;
12import org.hibernate.annotations.Parameter;
13
14@Entity
15@Table(name = "ADDRESS")
16@Access(value=AccessType.FIELD)
17public class Address {
18
19 @Column(name = "emp_id", unique = true, nullable = false)
20 @GeneratedValue(generator = "gen")
21 @GenericGenerator(name = "gen", strategy = "foreign", parameters = { @Parameter(name = "property", value = "employee") })
22 private long id;
23
24 @Column(name = "address_line1")
25 private String addressLine1;
26
27 @Column(name = "zipcode")
28 private String zipcode;
29
30 @Column(name = "city")
31 private String city;
32
33 @OneToOne
34 @PrimaryKeyJoinColumn
35 private Employee employee;
36
37 public long getId() {
38 return id;
39 }
40
41 public void setId(long id) {
42 this.id = id;
43 }
44
45 public String getAddressLine1() {
46 return addressLine1;
47 }
48
49 public void setAddressLine1(String addressLine1) {
50 this.addressLine1 = addressLine1;
51 }
52
53 public String getZipcode() {
54 return zipcode;
55 }
56
57 public void setZipcode(String zipcode) {
58 this.zipcode = zipcode;
59 }
60
61 public String getCity() {
62 return city;
63 }
64
65 public void setCity(String city) {
66 this.city = city;
67 }
68
69 public Employee getEmployee() {
70 return employee;
71 }
72
73 public void setEmployee(Employee employee) {
74 this.employee = employee;
75 }
76
77 @Override
78 public String toString() {
79 return "AddressLine1= " + addressLine1 + ", City=" + city
80 + ", Zipcode=" + zipcode;
81 }
82}
所有我需要解决的问题是用@Id
标注注主键字段,我将我的id字段声明更改为下,问题解决了。
1@Id
2@Column(name = "emp_id", unique = true, nullable = false)
3@GeneratedValue(generator = "gen")
4@GenericGenerator(name = "gen", strategy = "foreign", parameters = { @Parameter(name = "property", value = "employee") })
5private long id;
這是一個簡單的修正,但有一個情況讓它變得更加困惑。通常, hibernate 會根據變量或 getter-setter 上使用的注释來自動找出存取豆的屬性的方式。
- ** 字段**: Hibernate 在这种情况下会搜索变量上的注释,正如我们在上面的地址类别中定义的那样:
@Access(value=AccessType.FIELD)
. - ** 属性**: Hibernate 在这种情况下会搜索接入设置方法上的注释,其语法是
@Access(value=AccessType.PROPERTY)
如果注释不是按访问类型定义的,那么我们也会得到这个例外。例如,如果访问类型是属性,并且我们已在豆类变量上添加了所有注释,我们将得到这个例外。
1package com.journaldev.hibernate.model;
2
3import javax.persistence.Access;
4import javax.persistence.AccessType;
5import javax.persistence.Column;
6import javax.persistence.Entity;
7import javax.persistence.GeneratedValue;
8import javax.persistence.GenerationType;
9import javax.persistence.Id;
10import javax.persistence.OneToOne;
11import javax.persistence.Table;
12
13import org.hibernate.annotations.Cascade;
14
15@Entity
16@Table(name = "EMPLOYEE")
17@Access(value=AccessType.FIELD)
18public class Employee {
19
20 private long id;
21
22 private String name;
23
24 private double salary;
25
26 private Address address;
27
28 @Id
29 @GeneratedValue(strategy = GenerationType.IDENTITY)
30 @Column(name = "emp_id")
31 public long getId() {
32 return id;
33 }
34
35 public void setId(long id) {
36 this.id = id;
37 }
38
39 @OneToOne(mappedBy = "employee")
40 @Cascade(value = org.hibernate.annotations.CascadeType.ALL)
41 public Address getAddress() {
42 return address;
43 }
44
45 public void setAddress(Address address) {
46 this.address = address;
47 }
48
49 @Column(name = "emp_name")
50 public String getName() {
51 System.out.println("Employee getName called");
52 return name;
53 }
54
55 public void setName(String name) {
56 System.out.println("Employee setName called");
57 this.name = name;
58 }
59
60 @Column(name = "emp_salary")
61 public double getSalary() {
62 return salary;
63 }
64
65 public void setSalary(double salary) {
66 this.salary = salary;
67 }
68
69 @Override
70 public String toString() {
71 return "Id= " + id + ", Name= " + name + ", Salary= " + salary
72 + ", {Address= " + address + "}";
73 }
74
75}
请注意,所有 JPA 注释都与 getter 方法一起使用,而访问类型定义为 Field,只需将访问类型更改为属性以解决此问题。