CyStack logo
  • Sản phẩm & Dịch vụ
  • Giải pháp
  • Bảng giá
  • Công ty
  • Tài liệu
Vi

vi

Mục lục

Trang chủBlogHướng dẫn fix lỗi Hiberna...
Fix Bug

Hướng dẫn fix lỗi Hibernate AnnotationException: No identifier specified for entity Class

3 phút đọc22/08/2025
CyStack Author
Chris Pham

Technical Writer

0 lượt xem
Reading Time: 3 minutes

Khám phá nguyên nhân và cách khắc phục lỗi Hibernate AnnotationException. Hướng dẫn chi tiết giúp bạn xử lý lỗi annotation hiệu quả trong Hibernate.

fix lỗi Hibernate AnnotationException

Gần đây, khi tôi làm việc trên một dự án Hibernate và thêm một vài entity bean, lúc chạy chương trình tôi đã gặp thông báo exception stack trace như dưới đây.

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)

Nguyên nhân dẫn đến lỗi trên là do tôi quên khai báo primary key trong Entity bean. Bean của tôi được định nghĩa như sau: 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;
	}
}

Tất cả những gì mình cần làm để khắc phục lỗi là thêm annotation @Id cho trường primary key. Mình đã sửa phần khai báo trường id như dưới đây và lỗi đã được giải quyết:

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

Đây là một lỗi dễ khắc phục, nhưng có một trường hợp khiến nó trở nên rắc rối hơn. Thông thường, Hibernate sẽ tự động xác định cách truy cập các thuộc tính của bean dựa trên việc bạn đặt annotation ở biến hoặc getter/setter. Tuy nhiên, chúng ta cũng có thể chỉ định rõ ràng kiểu truy cập cho entity bean. Có hai kiểu truy cập chính:

  1. Field: Hibernate sẽ tìm kiếm chú thích trên các biến trong trường hợp này, giống như chúng ta đã định nghĩa cho lớp Địa chỉ ở trên là @Access(value=AccessType.FIELD).
  2. Property: Hibernate sẽ tìm kiếm chú thích trên các phương thức getter-setter trong trường hợp này, cú pháp cho việc này là @Access(value=AccessType.PROPERTY)

Nếu các annotation không được khai báo đúng với kiểu truy cập đã định, bạn cũng sẽ gặp exception này. Ví dụ: nếu kiểu truy cập là Property nhưng tất cả annotation lại đặt trên biến, Hibernate sẽ báo lỗi. Dưới đây là một ví dụ class Employee.java sẽ gây ra exception này.

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 + "}";
	}

}

Hãy để ý rằng tất cả các annotation JPA đều được đặt trên các phương thức getter, trong khi access type lại được khai báo là Field. Chỉ cần đổi access type thành Property là sẽ giải quyết được vấn đề này.

Về tác giả

Chris Pham
Chris PhamTechnical Writer

I have over 5 years of experience writing technical documentation for tech products, making them accessible and user-friendly. My focus is always on providing clear and precise information. @#@ Tôi đã có hơn 5 năm kinh nghiệm viết tài liệu kỹ thuật cho các sản phẩm công nghệ, giúp người dùng dễ dàng tiếp cận và sử dụng. Tôi luôn tập trung vào việc cung cấp thông tin chính xác và dễ hiểu.

Cập nhật thông tin mới nhấtNhận các thông tin mới nhất về mối đe dọa, báo cáo an ninh mạng từ CyStack về hòm thư điện tử của bạn

Thảo luận (0)

Đăng nhập để thảo luận

Bài viết liên quan