Reputation: 4920
I have seen this question at SO which tends to lead towards Primitives and also seen this one from coderanch which tends to lead towards wrappers. Both are slightly old too.
I do not have any special needs just want to know a standard good practice.
Examples on web are mixed too. e.g some with go like this:
@Id
@Column(name = "CUSTOMER_ID")
public long customerId;
Others with Wrappers:
@Id
@Column(name = "CUSTOMER_ID")
public Long customerId;
Upvotes: 21
Views: 10859
Reputation: 3180
From an Hibernate point of view, it doesn't change anything as Hibernate uses the same Hibernate type to represent them.
However, as pointed out by Bytecode Ninja, you can't distinguish the default value of a primitive int 0 from a an assigned 0 while there is no possible ambiguity with a null (a null id always means a new entity), which is why I prefer to use a nullable wrapper type.
And this is the Hibernate recommendation. From the Reference Documentation:
4.1.2. Provide an identifier property (optional)
Cat has a property called id. This property maps to the primary key column of a database table. The property might have been called anything, and its type might have been any primitive type, any primitive "wrapper" type, java.lang.String or java.util.Date. If your legacy database table has composite keys, you can use a user-defined class with properties of these types (see the section on composite identifiers later in the chapter.)
The identifier property is strictly optional. You can leave them off and let Hibernate keep track of object identifiers internally. We do not recommend this, however.
In fact, some functionality is available only to classes that declare an identifier property:
Transitive reattachment for detached objects (cascade update or cascade merge) - see Section 10.11, “Transitive persistence” Session.saveOrUpdate() Session.merge() We recommend that you declare consistently-named identifier properties on persistent classes and that you use a nullable (i.e., non-primitive) type.
And I actually leverage this in my base class:
@MappedSuperclass
public class BaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Transient
public boolean isNew() {
return (this.id == null);
}
}
Please check the more details here:https://stackoverflow.com/posts/3537407/edit
Upvotes: 1
Reputation: 16089
Hibernate recommends you:
We recommend that you declare consistently-named identifier properties on persistent classes and that you use a nullable (i.e., non-primitive) type. more
Upvotes: 7
Reputation:
I think that answer is included in nullable element in @Column annotation. If it can be nullable than wrapped primitive is ok. But on nullable=false columns ( as ID is) primitives are better. You will get extra checking because null cannot be cast to int/long.
Upvotes: 2
Reputation: 1966
If you use primitives it will always hold a default value, in this case 0L for long, even if the value is not there in the database. And if you use the wrapper object it will be having a null value if the value is not in the database or the entity is not persisted yet.
Upvotes: 1
Reputation: 11113
The difference between the two is nullability. the primitive type is unable to be null, while the "Wrapped" type can be null.
I prefer to use the wrapped type as you can tell if the object has been saved/loaded to/from the database whether or not the id value is null.
I don't think there is a "best practice" here, maybe a matter of style?
Upvotes: 24