Consider the below entity:
This is actually pretty cool. I actually thought this might be some easy facility provided by Hibernate, but the JPA docs indicate differently. JPA will automatically save Enum properties to the database.
I ran the code with table creation enabled. This is what was created in PostGRE SQL.
There is a problem with this approach though. If we accidentally modified the sequence of the constants in the java file, it would make a mess of the records in the database.
The alternative is to use the enum values instead of the ordinals.
@Entity @Table(name = "STUDENT") public class Student { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "NAME") private String name; private Rating rating; //setter getters }where Rating is a simple Enum
public enum Rating { MOTIVATED,NEEDS_PUSH,MUST_MEET }I tried to save an object of Student in the the database:
public static void testCreate() { EntityManager entityManager = emFactory.createEntityManager(); EntityTransaction transaction = entityManager.getTransaction(); Student student = new Student(); student.setName("Robin"); student.setRating(Rating.MUST_MEET); transaction.begin(); entityManager.persist(student); transaction.commit(); }If we ran this code the record would be ......................... SAVED
This is actually pretty cool. I actually thought this might be some easy facility provided by Hibernate, but the JPA docs indicate differently. JPA will automatically save Enum properties to the database.
I ran the code with table creation enabled. This is what was created in PostGRE SQL.
3015 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport -
create table firstOne.STUDENT (
id bigserial not null,
NAME varchar(255),
rating int4,
primary key (id)
)
JPA requires that the ORM map any enum present in the entity with the value of the ordinal property. Since the value we used (MUST_MEET) occurred as the third value in the class, the record in the table held the value 2. (Ordinal for Enums are 0 based)There is a problem with this approach though. If we accidentally modified the sequence of the constants in the java file, it would make a mess of the records in the database.
The alternative is to use the enum values instead of the ordinals.
@Entity @Table(name = "ADRESSED_USER") public class User { //.... @Enumerated(EnumType.STRING) private Rating rating; // remaining code }The table now generated is:
3797 [main] DEBUG org.hibernate.tool.hbm2ddl.SchemaExport - create table firstOne.STUDENT ( id bigserial not null, NAME varchar(255), rating varchar(255), primary key (id) )The rating column is now a string column. If we look at the insert SQL now:
insert into firstOne.STUDENT (NAME, rating) values (?, ?)What if we need to get all records of a particular rating ?
public static void findMustMeet() { EntityManager entityManager = emFactory.createEntityManager(); final Query query = entityManager .createQuery("SELECT student FROM Student as student " + "WHERE student.rating = :rating"); query.setParameter("rating", Rating.MUST_MEET); System.out.println(((Student)query.getSingleResult()).getName()); }The code executes a JPA Query to return a record with a RATING of MUST_MEET. The logs indicate the same:
5328 [main] DEBUG org.hibernate.engine.query.HQLQueryPlan - HQL param location recognition took 31 mills (SELECT student FROM Student as student WHERE student. rating = :rating) ... 5375 [main] DEBUG org.hibernate.SQL - select student0_.id as id0_, student0_.NAME as NAME0_, student0_.rating as rating0_ from firstOne.STUDENT student0_ where student0_.rating=? limit ? ... 5375 [main] DEBUG org.hibernate.type.EnumType - Binding 'MUST_MEET' to paramete r: 1
No comments:
Post a Comment