271

Why am I getting this exception?

package com.domain.idea;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.hibernate.annotations.AccessType;

/**
 * object model for the view [InvestmentReturn].[vMAE_MFE]
 */
@Entity
@Table(name="vMAE_MFE", schema="InvestmentReturn")
@AccessType("field")
public class MAE_MFEView
{
    /**
     * trade property is a SuggestdTradeRecommendation object
     */
    @OneToOne(fetch = FetchType.LAZY , cascade = { CascadeType.PERSIST })
    @JoinColumn(name = "suggestedTradeRecommendationID")
    private SuggestedTradeRecommendation trade;

    /**
     * Most Adeverse Excursion value
     */
    private int MAE;

    public int getMAE()
    {
        return MAE;
    }

    /**
     * Most Favorable Excursion value
     */
    private int MFE;

    public int getMFE()
    {
        return MFE;
    }

    /**
     * @return trade property
     * see #trade
     */
    public SuggestedTradeRecommendation getTrade()
    {
        return trade;
    }
}

Update: I've changed my code to look like this:

package com.domain.idea;

import javax.persistence.CascadeType;
import javax.persistence.FetchType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.hibernate.annotations.AccessType;

/**
 * object model for the view [InvestmentReturn].[vMAE_MFE]
 */
@Entity
@Table(name="vMAE_MFE", schema="InvestmentReturn")
@AccessType("field")
public class MAE_MFEView
{
    /**
     * trade property is a SuggestdTradeRecommendation object
     */
    @Id
    @OneToOne(fetch = FetchType.LAZY , cascade = { CascadeType.PERSIST })
    @JoinColumn(name = "suggestedTradeRecommendationID")
    private SuggestedTradeRecommendation trade;

    /**
     * Most Adeverse Excursion value
     */
    private int MAE;

    public int getMAE()
    {
        return MAE;
    }

    /**
     * Most Favorable Excursion value
     */
    private int MFE;

    public int getMFE()
    {
        return MFE;
    }

    /**
     * @return trade property
     * see #trade
     */
    public SuggestedTradeRecommendation getTrade()
    {
        return trade;
    }
}

but now I'm getting this exception:

Caused by: org.hibernate.MappingException: Could not determine type for: com.domain.idea.SuggestedTradeRecommendation, at table: vMAE_MFE, for columns: [org.hibernate.mapping.Column(trade)]
    at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:292)
    at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:276)
    at org.hibernate.mapping.RootClass.validate(RootClass.java:216)
    at org.hibernate.cfg.Configuration.validate(Configuration.java:1135)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1320)
    at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:669)
    ... 145 more
Vlad Mihalcea
  • 142,745
  • 71
  • 566
  • 911
Ramy
  • 20,541
  • 41
  • 103
  • 153
  • btw, unrelated to the question, that's a rather long stacktrace. You have some repeating invocations. Are you sure everything is correct there. – Bozho Dec 07 '10 at 20:46
  • not too sure why the stack-traces are always so long. I think there are a lot of background services running that are affected. – Ramy Dec 07 '10 at 21:40
  • Pay attention if your id is not static or some attributes on your class. It happened with me :) – Gean Felipe Aug 09 '18 at 15:05

15 Answers15

536

You are missing a field annotated with @Id. Each @Entity needs an @Id - this is the primary key in the database.

If you don't want your entity to be persisted in a separate table, but rather be a part of other entities, you can use @Embeddable instead of @Entity.

If you want simply a data transfer object to hold some data from the hibernate entity, use no annotations on it whatsoever - leave it a simple pojo.

Update: In regards to SQL views, Hibernate docs write:

There is no difference between a view and a base table for a Hibernate mapping. This is transparent at the database level

tetsuo
  • 10,726
  • 3
  • 32
  • 35
Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • 3
    I have to have an @Id field? My view doesn't have, strictly speaking, an ID. – Ramy Dec 07 '10 at 20:41
  • What do you mean "view". There is no "view" in Hibernate. There's only model. – Bozho Dec 07 '10 at 20:42
  • 1
    well, assign some id to the view. Can't go without it. Each row (object) has to be uniquely identified. – Bozho Dec 07 '10 at 20:48
  • getting a new exception after adding @Id – Ramy Dec 07 '10 at 21:56
  • @Ramy - simply adding `@Id` solves nothing. You have to add a new field, or devise an EmbeddedId. In short - you need to refine your data model. It's beyond me to determine what's best in this situation (I don't know the model) – Bozho Dec 07 '10 at 21:59
  • ok, I added a new field called ID (actually the same value as the field I had previously annotated as @Id). I then annotated the new field as @Id and @Column(name = "Id") Looks like the exception is gone. – Ramy Dec 07 '10 at 23:03
  • 3
    Thank you! This fixed an annoying NullPointerFromHellException! – malix Jul 18 '14 at 21:20
  • I think I have a scenario where ID is not needed but the data is still stored in a separate table. For example, a "sub-table" with a FK to the parent table. The sub-table doesn't have a PK. It's parent child model, where the child has not meaning living on it's own. Strange hibernate doesn't support it. – AlikElzin-kilaka Jan 22 '15 at 15:39
  • 2
    In other words, doesn't hibernate support tables **without** primary keys? – AlikElzin-kilaka Jan 22 '15 at 15:45
  • I think technically it support it, but it won't work very well. But that's true even outside hibernate - it's not a good idea to have a table without a primary key in general. – Bozho Feb 15 '15 at 13:54
  • 3
    I would like to represent a table doesn't have a PK. Is it not possible? – Yeung Jan 19 '16 at 05:58
  • I had view and I got the same error which i resolved by having @Id on one of the field (ofc primary key). Thanks – Manglesh Jun 08 '17 at 16:02
  • Thanks, after adding the `ID` to my `entity` it work now . – Osama Al-Banna Mar 22 '19 at 10:46
291

For me, javax.persistence.Id should be used instead of org.springframework.data.annotation.Id. For anyone who encountered this issue, you can check if you imported the right Id class.

This usually happens if you use IntelliJ's (and perhaps other IDEs too) auto-suggest feature without carefully looking at what the import will be.

likejudo
  • 3,396
  • 6
  • 52
  • 107
Searene
  • 25,920
  • 39
  • 129
  • 186
76

This error can be thrown when you import a different library for @Id than Javax.persistance.Id ; You might need to pay attention this case too

In my case I had

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Table;

import org.springframework.data.annotation.Id;

@Entity
public class Status {

    @Id
    @GeneratedValue
    private int id;

when I change the code like this, it got worked

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Table;

import javax.persistence.Id;

@Entity
public class Status {

    @Id
    @GeneratedValue
    private int id;
Tadele Ayelegn
  • 4,126
  • 1
  • 35
  • 30
  • 5
    valuable advice.. deprecate org.springframework.data.annotation.Id plz – Christian Meyer Jul 30 '19 at 21:13
  • Thanks so much... I know many people catch small details like this, and go after the less obvious answers. but thanks SO MUCH for this. I spend like 30 minutes on this issue, and learned a valuable lesson about taking my time lol – William Tolliver Aug 09 '23 at 02:25
14

The code below can solve the NullPointerException.

@Id
@GeneratedValue
@Column(name = "STOCK_ID", unique = true, nullable = false)
public Integer getStockId() {
    return this.stockId;
}
public void setStockId(Integer stockId) {
    this.stockId = stockId;
}

If you add @Id, then you can declare some more like as above declared method.

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
11

TL;DR

You are missing the @Id entity property, and that's why Hibernate is throwing that exception.

Entity identifiers

Any JPA entity must have an identifier property, that is marked with the Id annotation.

There are two types of identifiers:

  • assigned
  • auto-generated

Assigned identifiers

An assigned identifier looks as follows:

@Id
private Long id;

Notice that we are using a wrapper (e.g., Long, Integer) instead of a primitive type (e.g., long, int). Using a wrapper type is a better choice when using Hibernate because, by checking if the id is null or not, Hibernate can better determine if an entity is transient (it does not have an associated table row) or detached (it has an associated table row, but it's not managed by the current Persistence Context).

The assigned identifier must be set manually by the application prior to calling persist:

Post post = new Post();
post.setId(1L);

entityManager.persist(post);

Auto-generated identifiers

An auto-generated identifier requires the @GeneratedValue annotation besides the @Id:

@Id
@GeneratedValue
private int id;

There are 3 strategies Hibernate can use to auto-generate the entity identifier:

  • IDENTITY
  • SEQUENCE
  • TABLE

The IDENTITY strategy is to be avoided if the underlying database supports sequences (e.g., Oracle, PostgreSQL, MariaDB since 10.3, SQL Server since 2012). The only major database that does not support sequences is MySQL.

The problem with IDENTITY is that automatic Hibernate batch inserts are disabled for this strategy.

The SEQUENCE strategy is the best choice unless you are using MySQL. For the SEQUENCE strategy, you also want to use the pooled optimizer to reduce the number of database roundtrips when persisting multiple entities in the same Persistence Context.

The TABLE generator is a terrible choice because it does not scale. For portability, you are better off using SEQUENCE by default and switch to IDENTITY for MySQL only.

Vlad Mihalcea
  • 142,745
  • 71
  • 566
  • 911
6

I think this issue following model class wrong import.

    import org.springframework.data.annotation.Id;

Normally, it should be:

    import javax.persistence.Id;
4

Using @EmbeddableId for the PK entity has solved my issue.

@Entity
@Table(name="SAMPLE")
 public class SampleEntity implements Serializable{
   private static final long serialVersionUID = 1L;

   @EmbeddedId
   SampleEntityPK id;

 }
3
  1. This error occurs due to importing the wrong package:
    import javax.persistence.Id;
  2. And you should always give the primary key to the table, otherwise it will give an error.
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
2

I know sounds crazy but I received such error because I forget to remove

private static final long serialVersionUID = 1L;

automatically generated by Eclipse JPA tool when a table to entities transformation I've done.

Removing the line above that solved the issue

ittradco
  • 173
  • 1
  • 11
2

This error was caused by importing the wrong Id class. After changing org.springframework.data.annotation.Id to javax.persistence.Id the application run

1

In my case: @Id annotation was: "org.springframework.data.annotation.Id;" After replacing it with that of package: "javax.persistence.Id" the app worked fine.

0

I had faced same issue while creating session with hibernate using Intelij IDEA. Error was :

org.hibernate.AnnotationException: No identifier specified for entity

This error can caused if @ID annotation is not used in entity class but in my case

Solution Worked for me :

I removed the below import statement from my DAO class

import jakarta.persistence.*;

and added

import javax.persistence.*;

as many users suggested to do .

S G
  • 1
  • 5
0

As somebody has already mentioned the Entity class is missing @Id annotation which is must in case you are persisting your data. Again the @Id must be of same same library as of the @Entity.

Meaning:

javax.persistence.Entity will not work with org.springframework.data.annotation.Id. Both the Entity and Id must either part of Spring Data or Java Persistence API. It is advisable to use Java Persistence API as it is generic.

Aditya Bhuyan
  • 328
  • 6
  • 10
0

There can be two areas where we need to look after. i. correct imports ii. missing annotations

annotation required is

import javax.persistence.Id;

and annotation needed is

@Id

Sample Java Class

package com.oracle.dto;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;

import lombok.AccessLevel;
import lombok.Data;
import lombok.Setter;

@Entity
@Data
public class Question {
    @Id
    @Setter(value = AccessLevel.NONE)
    @GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "queGen")
    @SequenceGenerator(name = "queGen",sequenceName = "questionS",initialValue = 1,allocationSize = 1)
    private Integer qId;
    @Column(name="question_text",length = 200)
    private String question;
    @OneToOne
    @JoinColumn(name = "answerId")
    private Answer answer;
}

Pratik Gaurav
  • 661
  • 7
  • 8
0

If your table has a combination of fields that make each row unique, you can use a composite key and don't need an id field.

For example

@Entity
@Table(name = "food_nutrient")
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@IdClass(CompositeKey.class)
@EqualsAndHashCode
public class FoodNutrient implements Serializable {

Where CompositeKey is another class like

public class CompositeKey implements Serializable {
    private Integer foodId;
    private Integer nutrientId;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        CompositeKey key = (CompositeKey) o;
        if (foodId != key.foodId) return false;
        return nutrientId == key.nutrientId;
    }

    @Override
    public int hashCode() {
        return Objects.hash(foodId, nutrientId);
    }
}

Then your table will have two primary keys with no id field

+--------------+--------------+------+-----+---------+-------+
| Field        | Type         | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+-------+
| amount       | float        | YES  |     | NULL    |       |
| fdc_id       | int          | YES  |     | NULL    |       |
| food_id      | int          | NO   | PRI | NULL    |       |
| label_source | varchar(16)  | YES  |     | NULL    |       |
| name         | varchar(255) | YES  |     | NULL    |       |
| nutrient_id  | int          | NO   | PRI | NULL    |       |
| pct_dv       | int          | YES  |     | NULL    |       |
| unit_name    | varchar(16)  | YES  |     | NULL    |       |
+--------------+--------------+------+-----+---------+-------+
tekknow
  • 23
  • 6