【问题标题】:Mapping Set<enum> using @ElementCollection使用 @ElementCollection 映射 Set<enum>
【发布时间】:2013-04-06 14:26:50
【问题描述】:

我有以下枚举:

package ir.raysis.tcs.rule.days;

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

我尝试将其映射为Set&lt;Days&gt; 天,如下所示:

@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<>();

但是,它会引发以下异常:

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)

如何正确映射它?

【问题讨论】:

    标签: java hibernate jpa enums set


    【解决方案1】:

    为未来的谷歌员工! 最后我设法解决了这个问题,我只需要将注释放在我的代码中的其他地方,

    @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;
    }
    

    如您所见,我在上面和 getter 方法之前编写了注释代码(而不是将其放在属性声明代码之前)并解决了问题,任何可以解释我原因的人将不胜感激。谢谢你

    【讨论】:

    • 值得补充的是,@Column(name = "daysOfWeek") 在这种情况下是集合表“天”(不是“规则”表)中的一列。
    • 我们在做几乎相同的事情,并且使用 Envers。最奇怪的是,在 JBoss Developer Studio (eclipse) 中,在 User(对于 Roles,一个枚举)中添加 @ElementCollection 会在模型的其余部分中创建构建错误。有人知道会发生什么吗?
    • 对我来说,它在变量本身上工作得很好。但如果我没记错的话,你应该为你的整个班级一致地配置这些注释,所以如果你把一个放在吸气剂上,你应该把所有在吸气剂上
    • 了解这些注释的 SQL 架构是什么样子会很有帮助。
    • 这不是属性与方法的问题。您在回答中使用了CollectionTable,在问题中使用了JoinTable
    【解决方案2】:

    尝试使用@CollectionTable 而不是@JoinTable

    【讨论】:

    • 谢谢回复,但这并没有解决问题 - 有什么想法吗?
    • 嗯...尝试摆脱 @ElementCollection 并将 targetClass 放在 @JoinTable 上。
    【解决方案3】:

    虽然另一个问题是正确的,但最简单的形式可能是:

    @ElementCollection
    @Enumerated
    private Set<EnumName> enumValues;
    

    其他所有内容都将按照约定而不是配置(连接表名称、列)进行设置。

    我强烈推荐使用@Enumerated(EnumType.STRING) - 查找原因。您可能需要@ElementCollection(fetch = FetchType.EAGER),具体取决于您在做什么(以及在哪里)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 2012-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多