[נפתר] org.hibernate.AnnotationException: לא צויין זיהוי עבור מחלקת ישות

לאחרונה עבדתי על פרויקט Hibernate והוספתי כמה דוגמיות של ישויות, כאשר הרצתי קיבלתי את השגיאה הבאה:

Initial SessionFactory creation failed.org.hibernate.AnnotationException: No identifier specified for entity: com.journaldev.hibernate.model.Address
org.hibernate.AnnotationException: No identifier specified for entity: com.journaldev.hibernate.model.Address
	at org.hibernate.cfg.InheritanceState.determineDefaultAccessType(InheritanceState.java:277)
	at org.hibernate.cfg.InheritanceState.getElementsToProcess(InheritanceState.java:224)
	at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:775)
	at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3788)
	at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3742)
	at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1410)
	at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1844)
	at com.journaldev.hibernate.util.HibernateUtil.buildSessionFactory(HibernateUtil.java:22)
	at com.journaldev.hibernate.util.HibernateUtil.getSessionFactory(HibernateUtil.java:34)
	at com.journaldev.hibernate.main.HibernateExample.main(HibernateExample.java:15)
Exception in thread "main" java.lang.ExceptionInInitializerError
	at com.journaldev.hibernate.util.HibernateUtil.buildSessionFactory(HibernateUtil.java:29)
	at com.journaldev.hibernate.util.HibernateUtil.getSessionFactory(HibernateUtil.java:34)
	at com.journaldev.hibernate.main.HibernateExample.main(HibernateExample.java:15)

הבעיה הייתה בכך ששכחתי לציין מפתח ראשי ביישות היישות שלי, הישות שלי הוגדרה כך; Address.java

package com.journaldev.hibernate.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;

@Entity
@Table(name = "ADDRESS")
@Access(value=AccessType.FIELD)
public class Address {

	@Column(name = "emp_id", unique = true, nullable = false)
	@GeneratedValue(generator = "gen")
	@GenericGenerator(name = "gen", strategy = "foreign", parameters = { @Parameter(name = "property", value = "employee") })
	private long id;

	@Column(name = "address_line1")
	private String addressLine1;

	@Column(name = "zipcode")
	private String zipcode;

	@Column(name = "city")
	private String city;

	@OneToOne
	@PrimaryKeyJoinColumn
	private Employee employee;

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getAddressLine1() {
		return addressLine1;
	}

	public void setAddressLine1(String addressLine1) {
		this.addressLine1 = addressLine1;
	}

	public String getZipcode() {
		return zipcode;
	}

	public void setZipcode(String zipcode) {
		this.zipcode = zipcode;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public Employee getEmployee() {
		return employee;
	}

	public void setEmployee(Employee employee) {
		this.employee = employee;
	}

	@Override
	public String toString() {
		return "AddressLine1= " + addressLine1 + ", City=" + city
				+ ", Zipcode=" + zipcode;
	}
}

כל מה שהייתי צריך לעשות כדי לתקן את הבעיה היה להוסיף את האנוטציה @Id על שדה המפתח הראשי שלי. שיניתי את ההכרזה על שדת הזיהוי שלי למטה והבעיה נפתרה.

@Id
@Column(name = "emp_id", unique = true, nullable = false)
@GeneratedValue(generator = "gen")
@GenericGenerator(name = "gen", strategy = "foreign", parameters = { @Parameter(name = "property", value = "employee") })
private long id;

זהו תיקון פשוט אך יש תרחיש אחד שבו זה מתעקש יותר. לרוב, Hibernate מבין באופן אוטומטי איך לגשת אל תכונות הבונה בהתבסס על האנוטציות המשמשות על משתנה או גטר-סטר. אך, ניתן להגדיר את סוג הגישה באופן פורמלי עבור יישויות היישות שלנו. קיימים שני סוגי גישה:

  1. Field: Hibernate יחפש אנוטציות על משתנים במקרה זה, כמו שהגדרנו עבור המחלקה Address למעלה כך @Access(value=AccessType.FIELD).
  2. Property: Hibernate יחפש אנוטציות על שיטות הגטר-סטר במקרה זה, סינטקס עבור זה הוא @Access(value=AccessType.PROPERTY)

אם האנוטציות לא מוגדרות על פי סוג הגישה, נקבל גם את השגיאה הזו. לדוגמה אם סוג הגישה הוא נכס והוספנו את כל האנוטציות על משתני היישות, נקבל את השגיאה הזו. דוגמה למחלקה שתזרוק את השגיאה הזו ניתן לראות למטה. Employee.java

package com.journaldev.hibernate.model;

import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;

@Entity
@Table(name = "EMPLOYEE")
@Access(value=AccessType.FIELD)
public class Employee {

	private long id;

	private String name;

	private double salary;

	private Address address;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "emp_id")
	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	@OneToOne(mappedBy = "employee")
	@Cascade(value = org.hibernate.annotations.CascadeType.ALL)
	public Address getAddress() {
		return address;
	}

	public void setAddress(Address address) {
		this.address = address;
	}

	@Column(name = "emp_name")
	public String getName() {
		System.out.println("Employee getName called");
		return name;
	}

	public void setName(String name) {
		System.out.println("Employee setName called");
		this.name = name;
	}

	@Column(name = "emp_salary")
	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	@Override
	public String toString() {
		return "Id= " + id + ", Name= " + name + ", Salary= " + salary
				+ ", {Address= " + address + "}";
	}

}

שים לב שכל האנוטציות של JPA משמשות עם שיטות גטר-סטר בעוד סוג הגישה מוגדר כשדה, פשוט שנה את סוג הגישה לנכס כדי לפתור את הבעיה הזו.

Source:
https://www.digitalocean.com/community/tutorials/solved-org-hibernate-annotationexception-no-identifier-specified-for-entity-class