开发者

JPA/Hibernate, @Embedded and Enum

开发者 https://www.devze.com 2022-12-19 17:28 出处:网络
I\'m trying to persist an Enum as an Embedded value (ideally using it\'s String representation, but even ordinal would be ok right now)

I'm trying to persist an Enum as an Embedded value (ideally using it's String representation, but even ordinal would be ok right now)

The Enum:

开发者_如何学JAVA@Embeddable
public enum DayOfTheWeek {
 SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;

 public int toCalendar() throws EnumConstantNotPresentException{
  switch (this) {
  case SUNDAY:
   return Calendar.SUNDAY;
  case MONDAY:
   return Calendar.MONDAY;
  case TUESDAY:
   return Calendar.TUESDAY;
  case WEDNESDAY:
   return Calendar.WEDNESDAY;
  case THURSDAY:
   return Calendar.THURSDAY;
  case FRIDAY:
   return Calendar.FRIDAY;
  case SATURDAY:
   return Calendar.SATURDAY;
  }
  throw new EnumConstantNotPresentException(this.getClass(), "Unknown value ["+this.name()+"]");
 }

 public static DayOfTheWeek fromCalendarDay(int day) {
  switch (day) {
  case Calendar.SUNDAY:
   return SUNDAY;
  case Calendar.MONDAY:
   return MONDAY;
  case Calendar.TUESDAY:
   return TUESDAY;
  case Calendar.WEDNESDAY:
   return WEDNESDAY;
  case Calendar.THURSDAY:
   return THURSDAY;
  case Calendar.FRIDAY:
   return FRIDAY;
  case Calendar.SATURDAY:
   return SATURDAY;
  }
  return null;
 }

 public static DayOfTheWeek getByDate(Date date) {
  Calendar calendar = GregorianCalendar.getInstance();
  calendar.setTime(date);
  return fromCalendarDay(calendar.get(Calendar.DAY_OF_WEEK));
 }

 @Override
 /**
  * Should return the localized day of the week
  */
 public String toString() {
  Calendar c = new GregorianCalendar();
  c.set(Calendar.DAY_OF_WEEK, this.toCalendar());
  SimpleDateFormat sdf = (SimpleDateFormat) SimpleDateFormat
    .getInstance();
  sdf.applyPattern("EEEEEEEEEE");

  return sdf.format(c.getTime());
 }

}

The Class :

@Entity
public class Day implements Serializable {

 ...

 @Enumerated
 @Embedded
 private DayOfTheWeek dayOfTheWeek;

 ...

 @Id
 @GeneratedValue
 private Long id;

 public void setId(Long id) {
  this.id = id;
 }

 public Long getId() {
  return id;
 }

 public void setDayOfTheWeek(DayOfTheWeek dayOfTheWeek) {
  this.dayOfTheWeek = dayOfTheWeek;
 }

 public DayOfTheWeek getDayOfTheWeek() {
  return dayOfTheWeek;
 }

 ...
}

Now, here is the interesting part of the stack when persisting "Day" :

org.springframework.orm.hibernate3.HibernateSystemException: No default constructor for entity: xxx.yyyy.zzz.DayOfTheWeek; nested exception is org.hibernate.InstantiationException: No default constructor for entity: xxx.yyyy.zzz.DayOfTheWeek

I've tried several things and couldn't get it to work in any way, any idea ?


Remove the @Embedded and @Embeddable annotations just use the @Enumerated(EnumType.STRING) to get it as a string.

As a side note, consider defining your enum like this to avoid the switch

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public enum DayOfTheWeek {
    SUNDAY {
        @Override
        public int toCalendar() {
            return Calendar.SUNDAY;
        }

    },
    MONDAY {
        @Override
        public int toCalendar() {
            return Calendar.MONDAY;
        }
    },
    TUESDAY {
        @Override
        public int toCalendar() {
            return Calendar.TUESDAY;
        }
    },
    WEDNESDAY {
        @Override
        public int toCalendar() {
            return Calendar.WEDNESDAY;
        }
    },
    THURSDAY {
        @Override
        public int toCalendar() {
            return Calendar.THURSDAY;
        }
    },
    FRIDAY {
        @Override
        public int toCalendar() {
            return Calendar.FRIDAY;
        }
    },
    SATURDAY {
        @Override
        public int toCalendar() {
            return Calendar.SATURDAY;
        }
    };

    public abstract int toCalendar();

    public static DayOfTheWeek fromCalendarDay(int day) {

        for (DayOfTheWeek dayOfWeek : DayOfTheWeek.values()) {
            if (dayOfWeek.toCalendar() == day) {
                return dayOfWeek;
            }
        }

        return null; // Consider throwing IllegalArgumentException
    }

    public static DayOfTheWeek getByDate(Date date) {
        Calendar calendar = GregorianCalendar.getInstance();
        calendar.setTime(date);
        return fromCalendarDay(calendar.get(Calendar.DAY_OF_WEEK));
    }

    @Override
    /*
     * Should return the localized day of the week
     */
    public String toString() {
        Calendar c = new GregorianCalendar();
        c.set(Calendar.DAY_OF_WEEK, this.toCalendar());
        SimpleDateFormat sdf = (SimpleDateFormat) SimpleDateFormat
                .getInstance();
        sdf.applyPattern("EEEEEEEEEE");

        return sdf.format(c.getTime());
    }

}


Why do you want the enum to be @Embeddable. What is wrong with simply annotating it as a column?

@Enumerated(EnumType.STRING)
@Column(name = "...")
public DayOfTheWeek getDayOfTheWeek() {
    return dayOfTheWeek;
}


I know that the question has been answered and it was a long time ago.

I just wanted to suggest further enhancement to your enum construction. Here it goes:

    public enum DayOfTheWeek {
        SUNDAY(Calendar.SUNDAY),
        MONDAY(Calendar.MONDAY),
        TUESDAY(Calendar.TUESDAY),
        WEDNESDAY(Calendar.WEDNESDAY),
        THURSDAY(Calendar.THURSDAY),
        FRIDAY(Calendar.FRIDAY),
        SATURDAY(Calendar.SATURDAY);

        DayOfTheWeek(int dayOfTheWeek){
            this.dayOfTheWeek = dayOfTheWeek;
        }
        int dayOfTheWeek;

        public int toCalendar(){
            return dayOfTheWeek;
        }

    }

Thank you, guys for your attention! Have fun!

0

精彩评论

暂无评论...
验证码 换一张
取 消