Mahozad
Mahozad

Reputation: 24532

Boxed vs primitive type as entity id

In JPA (Hibernate implementation) which type is better to use for id of the entity: Boxed type (e.g. Integer) or Unboxed type (e.g. int)?

A friend said that you should use Boxed types because when you create a new entity in your program, Hibernate sees that the id is null and understands that it should create a new row in database (In contrast if id is not null Hibernate may update an existing row in databse).

But the id of my entities was int and it worked well without any error and we know that the default value of primitive instance variables is 0. So he said that maybe hibernate treats 0 as special and assumes that the object is a new one.

Upvotes: 26

Views: 6240

Answers (6)

Angad Bansode
Angad Bansode

Reputation: 923

Unique identifiers of entities and collections may be of any basic type except binary, blob and clob. (Composite identifiers are also allowed, see below.)

The basic value types have corresponding Type constants defined on org.hibernate.Hibernate. For example, Hibernate.STRING represents the string type.

Upvotes: -2

Pradip Karki
Pradip Karki

Reputation: 702

I prefer Boxed Type in entity model because that gives flexibility to use Boxed Type in generics. For instance, here Entity model can have only the type that extends to Serializable for id. It will be useful later in service layer where we can perform various operations on primary key.

public interface BaseEntity<E extends Serializable> extends Serializable {
  E getId();
}

Entity model could be like:

@Entity
public class PhoneNumber implements BaseEntity<Long> {
  private static final long serialVersionUID = 1L;

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "PHONE_NUMBER_ID")
  private Long id;

Upvotes: 1

John
John

Reputation: 373

There is no difference between primitive (e.g., int) and its wrapper(e.g., Integer) for entity id. Both are valid according to JPA specification. JPA provider is smart enough to track the state and life cycle of an entity. When entity id is 0 (primitive type) or NULL(wrapper type), JPA provider will generate an id for the entity if id generator is configured. Zero is not regarded as a valid entity id if id is auto generated.

Tested both cases with Cmobilecom JPA, and it works equally well. Off course, no performance difference can be noticed.

Disclaimer: I am a developer of Cmobilecom JPA, a light weight JPA implementation for both Java and Android.

Upvotes: 8

We can think of it like this:

When we have a value x :: Int, then 'x' is a computation which when evaluated will return either an Int or will be bottom (undefined).

When the program runs and x is evaluated, suppose it evalutes to an actual Int (not bottom). Then in the future any time x is evaluated, instead of redoing the entire computation, we only want to get the value out which we previously calculated.

What we do to accomplish this is to replace to thunk (computation) which calculates x with a thunk which simply returns the value which was computed before.

The problem is that every time you need to get x in the future, you have to follow this pointer to the (trivial) code which returns a value. THis gets expensive if you need these values frequently.

Enter unboxed values. An unboxed value is just that low-level value, not wrapped inside a thunk. This means that it is strict in the sense that it cannot be undefined without your program necessarily dying.

Upvotes: -3

Eugene
Eugene

Reputation: 120858

Well, we use non-primitives and we have a strong reason for it. Lots of our fields that are either int/Integer for example have an absolute business value of zero to be perfectly valid. Think of a debt field for example - it is more than OK if the field is zero, meaning you have no debt.

Problem is that with primitives, zero is a default value - so you might accidentally forget to set it for example via a setDebt, thus it might reach your database with a value that you never intended to go there. For this reason we use Integer with some validations that is should never be null for example; but even if we forget to add proper validations, that code will potentially break with a NullPointerException (preferably in tests) and I like an Exception more than inconsistent values in the database.

Upvotes: 11

gtgaxiola
gtgaxiola

Reputation: 9331

Seems Current Documentation recommends to use Boxed Type.

We recommend that you declare consistently-named identifier attributes on persistent classes and that you use a nullable (i.e., non-primitive) type.

Upvotes: 17

Related Questions