【问题标题】:@OneToOne relationship with JPA@OneToOne 与 JPA 的关系
【发布时间】:2016-01-10 13:02:48
【问题描述】:

我正在为我的大学做一个项目。这是一个类似于 AirBnb 的预订系统。系统内部有两个实体:请求和结构。没有相对请求就不能插入结构。所以我以这种方式对 Request 进行建模:

public class Request {
      //...attributes (with a Generated Id)..//

      @OneToOne(optional=false)
      @JoinColumn(
        name="structure_id", unique=true, nullable=false, updatable=false)
      private Structure structure;
}

和结构:

public class Structure{
      //...attributes (with a Generated Id)..//
     private Request request;

     @OneToOne(optional=false, mappedBy="structure")
     public Request getRequest() {
     return request;
}

每次我尝试测试应用程序时,它都会失败

Persistence.createEntityManagerFactory()

带有此错误消息:

Stacktrace:] 有根本原因 org.hibernate.MappingException:无法确定类型:it.ispw.efco.nottitranquille.model.Structure,在表:请求,列:[org.hibernate.mapping.Column(结构)] 在 org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:396) 在 org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:369) 在 org.hibernate.mapping.Property.isValid(Property.java:225) 在 org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:529) 在 org.hibernate.mapping.RootClass.validate(RootClass.java:265) 在 org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:329) 在 org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:443) 在 org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:879) 在 org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:58) 在 javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55) 在 javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39) 在 it.ispw.efco.nottitranquille.model.JPAInitializer.(JPAInitializer.java:25) 在 it.ispw.efco.nottitranquille.model.JPAInitializer.getEntityManager(JPAInitializer.java:43) 在 it.ispw.efco.nottitranquille.model.CatalogueDAO.saveRequest(CatalogueDAO.java:26) 在 it.ispw.efco.nottitranquille.view.SearchBean.validate(SearchBean.java:79) 在 org.apache.jsp.search_jsp._jspService(search_jsp.java:134) 在 org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:729) 在 org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:438) 在 org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396) 在 org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:729) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 在 org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219) 在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) 在 org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) 在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 在 org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:617) 在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518) 在 org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091) 在 org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668) 在 org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1521) 在 org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1478) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 在 org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 在 java.lang.Thread.run(Thread.java:745)

无法在数据库中映射这种关系? (Windows 10 上的 MySQL 5.7.10) 没有结构,请求就无法生存,反之亦然。 我该如何解决? 非常感谢您!

编辑 1: 我现在收到了这个新错误:

org.hibernate.TransientPropertyValueException:对象引用了一个未保存的瞬态实例 - 在刷新之前保存瞬态实例:it.ispw.efco.nottitranquille.model.Structure.request -> it.ispw.efco.nottitranquille.model.Request

这段代码对吗?请求应该保存链接到它的结构,对吧?

    Address address = new Address(//some fields//);
    Structure structure = new Structure(/*a name*/,address);
    Request request = new Request(structure);
    CatalogueDAO catalogueDAO = new CatalogueDAO();
    catalogueDAO.saveRequest(request);

编辑 2:

前面的问题通过在Request.structure的@OneToOne上添加(cascade = CascadeType.ALL)解决

但现在我明白了:

无法添加或更新子行:外键约束失败 (notti_tranquille.request, 约束FKbi1rasm9sdgrouh2mdklvi2q 外键 (id) 引用 structure (address_id))

Structure 还有一个属性:Address,有自己的 Id 和简单的属性

@OneToOne @MapsId
private Address address;

但是,如果我检查 JPA 创建的表,我发现表结构具有主键 address_id...为什么?

【问题讨论】:

  • 如果启用了级联,em.persist(Request) 将保存结构。如果没有,那么你调用 em.persist(Request) 和 em.persist(Structure) ...就像 JPA 教程说的那样
  • 是的,你是对的!而且我也必须为地址启用级联。但是address_id仍然是结构的主键...
  • 我成功了!正如谢尔盖所​​说,我删除了@JoinColumn,并从地址中删除了@MapsId。我还在 Request 的构造函数中添加了这一行:structure.setRequest(this)。现在一切正常!

标签: java mysql hibernate jpa


【解决方案1】:

为什么在getRequest()上面有注解?试试这个

public class Structure{
  //...attributes (with a Generated Id)..//
@OneToOne(optional=false, mappedBy="structure")
 private Request request;


 public Request getRequest() {
 return request;

}

你有没有尝试删除这个注解@JoinColumn( name="structure_id", unique=true, nullable=false, updatable=false) 。 在这里你可以找到工作示例one to one example

【讨论】:

  • 我复制了文档示例(您可以在 IntelliJ IDEA 15 中的 @OneToOne 注释上使用 Ctrl+Q 找到该示例)
  • 我试过了,结果是这个:org.hibernate.AnnotationException: Referenced property not a (One|Many)ToOne: it.ispw.efco.nottitranquille.model.Request.structure in mappedBy of it.ispw.efco.nottitranquille.model.Structure.request
  • 在 JPA 中你可以注释一个字段或一个属性(getter),所以这不是问题
猜你喜欢
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-12
  • 1970-01-01
  • 1970-01-01
  • 2020-08-01
  • 2021-05-22
相关资源
最近更新 更多