33

I have the following enum:

package ir.raysis.tcs.rule.days;

public enum Days {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY;
}

I tried to map it as a Set<Days> days as follows:

@ElementCollection(targetClass = Days.class) 
@JoinTable(name = "days",joinColumns = @JoinColumn(name = "rule_id")) 
@Column(name ="daysOfWeek", nullable = false) @Enumerated(EnumType.STRING) 
private Set<Days> days = new HashSet<>();

However, it throws the following exception:

Initial SessionFactory creation failed.org.hibernate.MappingException: Could not determine type for: java.util.Set, at table: rule, for columns: [org.hibernate.mapping.Column(days)]
Apr 14, 2013 4:15:17 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [jsp] in context with path [/ptcs] threw exception [javax.servlet.ServletException: java.lang.ExceptionInInitializerError] with root cause
org.hibernate.MappingException: Could not determine type for: java.util.Set, at table: rule, for columns: [org.hibernate.mapping.Column(days)]
    at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:306)
    at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:290)
    at org.hibernate.mapping.Property.isValid(Property.java:217)
    at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:464)
    at org.hibernate.mapping.RootClass.validate(RootClass.java:235)
    at org.hibernate.cfg.Configuration.validate(Configuration.java:1362)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1865)
    at ir.raysis.tcs.db.HibernateUtil.<clinit>(HibernateUtil.java:18)
    at ir.raysis.tcs.db.SaveUpadteDelete.save(SaveUpadteDelete.java:33)
    at ir.raysis.tcs.db.dBAllFunc.save(dBAllFunc.java:35)
    at ir.raysis.tcs.db.AbsDBObject.save(AbsDBObject.java:45)
    at ir.raysis.tcs.action.CreateMemberAction.execute(CreateMemberAction.java:31)
    at org.apache.jsp.action.createMember_jsp._jspService(createMember_jsp.java:79)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1770)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

How do I properly map it?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
MoienGK
  • 4,544
  • 11
  • 58
  • 92

3 Answers3

75

for future googlers! finally i managed to solve the problem, i just had to put the annotations somewhere else in my code ,

@ElementCollection(targetClass = Days.class)
@CollectionTable(name = "days", joinColumns = @JoinColumn(name = "rule_id"))
@Column(name = "daysOfWeek", nullable = false)
@Enumerated(EnumType.STRING)
public Set<Days> getDays() {
    return days;
}

as you can see i wrote the annotation code above and before the getter method(instead of placing it before the attribute declaration code) and problem solved, anyone who can explain me what causes this will be appreciated. thank you

MoienGK
  • 4,544
  • 11
  • 58
  • 92
  • 4
    Worth adding that @Column(name = "daysOfWeek") is in this case a column in collection table 'days' (not the 'rule' table). – malloc4k Dec 27 '14 at 12:49
  • We're doing virtually the same thing, and using Envers. Weirdest thing, in JBoss Developer Studio (eclipse), adding @ElementCollection in User (for Roles, an enum) creates build errors in most of the rest of the model. Anyone have an ideas what might be happening? – LinuxLars Feb 24 '15 at 20:33
  • 2
    for me it works just fine on the variable itself..But if i'm not mistaken u should configure these annotations consistently for your entire class, so if you put one on the getter you should place all on the getters – steelshark Nov 22 '15 at 13:31
  • 1
    It would be helpful to know what the SQL schema looked like for these annotations. – Casey Feb 28 '18 at 09:28
  • 5
    It is not an attribute vs method issue. You have used `CollectionTable` in your answer vs `JoinTable` in your question – saifulislampi Nov 05 '19 at 09:07
  • You might want to use an explicit fetching strategy on the `@ElementCollection` annotation as well. For example: `@ElementCollection(fetch = FetchType.EAGER)` – Simeon Leyzerzon Jan 27 '20 at 03:29
6

Try using @CollectionTable and not @JoinTable

Pace
  • 41,875
  • 13
  • 113
  • 156
5

While the other question is correct, the most simple form could be:

@ElementCollection
@Enumerated
private Set<EnumName> enumValues;

everything else would be set by convention over configuration (join-table-name, columns).

I highly recommend using @Enumerated(EnumType.STRING) - look it up why. And you might need @ElementCollection(fetch = FetchType.EAGER) depending on what (and where) you're doing.

icyerasor
  • 4,973
  • 1
  • 43
  • 52