Tutorial

[Solved] org.hibernate.AnnotationException: No identifier specified for entity Class

Published on August 3, 2022
author

Pankaj

[Solved] org.hibernate.AnnotationException: No identifier specified for entity Class

Recently I was working on a hibernate project and I have added few entity beans, when executed I got below exception stack trace.

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)

The issue was coming because I forgot to specify primary key in my Entity bean, my bean was defined as; 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;
	}
}

All I needed to fix the issue was to annotate the primary key field with @Id annotation. I changed my id field declaration to below and issue was resolved.

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

This is an easy fix but there is one scenario where it becomes more confusing. Usually hibernate automatically figures out the way to access the bean properties based on the annotations used on variable or getter-setter. However, We can explicitly define access type for our entity beans. There are two types of access types:

  1. Field: Hibernate will look for annotations on variables in this case, like we have defined for Address class above as @Access(value=AccessType.FIELD).
  2. Property: Hibernate will look for annotations on getter-setter methods in this case, syntax for this is @Access(value=AccessType.PROPERTY)

If the annotations are not defined as per access type, then also we will get this exception. For example if the access type is property and we have added all the annotations on bean variables, we will get this exception. A sample class that will throw this exception is given below. 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 + "}";
	}

}

Notice that all the JPA annotations are used with getter methods whereas access type is defined as Field, just change the access type to property to solve this issue.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar
Pankaj

author

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
February 8, 2022

I don’t understand the sense of the @Access. I have this options: use no @Access - and set @Id before my variables, so I have direct access without setters - and set @Id before my setters, so I have access with setters This works fine. Now I want to use @Access(AccessType.PROPERTY) but set the @Id before my variables and I get this error. I have to put the @Id before the setters but why should I use the @Access annotation? It does the same and didn’t overwrite the setting.

- John

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    April 6, 2021

    Thanks brother.Faced the same problem and tried a lot to solve it and finally was able to do so by visiting this webpage.

    - Mihir Sheth

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      June 6, 2020

      Thank you very much Pankaj. I was stuck with this issue for hours and finally figured it out here. You are a lifesaver.

      - Nitish

        JournalDev
        DigitalOcean Employee
        DigitalOcean Employee badge
        February 12, 2020

        Hi Pankaj I tried using both AccessType.FIELD and AccessType.PROPERTY in Hibernate Core {5.4.10.Final} but getting same error.

        - Avinash

          JournalDev
          DigitalOcean Employee
          DigitalOcean Employee badge
          January 28, 2020

          Hi , Is it possible to add the user defined sequence to the id, in this concept. Thanks Murali.K

          - Murali.

            JournalDev
            DigitalOcean Employee
            DigitalOcean Employee badge
            May 29, 2019

            I Got the exception in Hibernate 4 (4.3.10.Final) Caused by: org.hibernate.AnnotationException: No identifier specified for entity Solution : My Entity class was mapped only for ready only data. So I changed to @Embeddable annotaion instead of @Entity annotation. @Embeddable //@Entity @Table(name=“geonames”) public class Geoname implements Serializable { //no PK. or embedded key private String name; private String street; }

            - govindraju

              JournalDev
              DigitalOcean Employee
              DigitalOcean Employee badge
              April 26, 2019

              Hi Pankaj, Can you please tell how to configure id column if I’m doing XML configuration instead of annotations?

              - Madhavi

                JournalDev
                DigitalOcean Employee
                DigitalOcean Employee badge
                December 30, 2017

                Thanks mate, this was precisely my problem, great explanation to a not-so-easy-to-trace problem.

                - Jonck

                  JournalDev
                  DigitalOcean Employee
                  DigitalOcean Employee badge
                  April 15, 2016

                  Nice article. Thanks!

                  - Abdulah

                    Try DigitalOcean for free

                    Click below to sign up and get $200 of credit to try our products over 60 days!

                    Sign up

                    Join the Tech Talk
                    Success! Thank you! Please check your email for further details.

                    Please complete your information!

                    Become a contributor for community

                    Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

                    DigitalOcean Documentation

                    Full documentation for every DigitalOcean product.

                    Resources for startups and SMBs

                    The Wave has everything you need to know about building a business, from raising funding to marketing your product.

                    Get our newsletter

                    Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

                    New accounts only. By submitting your email you agree to our Privacy Policy

                    The developer cloud

                    Scale up as you grow — whether you're running one virtual machine or ten thousand.

                    Get started for free

                    Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

                    *This promotional offer applies to new accounts only.