Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Hibernate 5中映射单向一对一关系_Hibernate_Jpa - Fatal编程技术网

在Hibernate 5中映射单向一对一关系

在Hibernate 5中映射单向一对一关系,hibernate,jpa,Hibernate,Jpa,我的问题很简单,为什么hibernate在我持久化一个帐户实体时,不将帐户实体的主键自动带到用户实体,比如@mapsId 如果我们考虑到这个映射: @Entity @Table(name="account") @Getter @Setter public class Account implements Serializable{ /** * */ private static final long serialVersionUID = 1L;

我的问题很简单,为什么hibernate在我持久化一个帐户实体时,不将帐户实体的主键自动带到用户实体,比如@mapsId

如果我们考虑到这个映射:

@Entity
@Table(name="account")
@Getter
@Setter
public class Account implements Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name="id")
    @GeneratedValue(strategy= GenerationType.AUTO, generator="native")
    @GenericGenerator(name = "native", strategy = "native")
    private int accountId;

    @Column(name="email")
    private String email;

    @OneToOne(cascade = CascadeType.ALL)
    @PrimaryKeyJoinColumn(name="id", referencedColumnName="pk_account$user")
    private User user;

}

@Entity
@Table(name="user")
@Getter
@Setter
public class User implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name="pk_account$user")
    private int userId;

    @Column(name="identification_number")
    private String identificationNumber;

}
然后我做这个:

public static void main( String[] args )
    {
        SessionFactory sessionFactory;
        Configuration configuration= new Configuration();
        configuration.configure();
        sessionFactory=configuration.buildSessionFactory();
        Session session= sessionFactory.openSession();
        session.beginTransaction();
        Account account= new Account();
        account.setEmail("new@gmail.com");

        User user= new User();
        user.setIdentificationNumber("11462727272");
        account.setUser(user);

        session.persist(account);
        session.getTransaction().commit();

    }
我有一个错误:

Hibernate: insert into account (email) values (?)
Hibernate: insert into user (identification_number, pk_account$user) values (?, ?)
    Jun 04, 2018 5:41:16 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
    WARN: SQL Error: 1452, SQLState: 23000
    Jun 04, 2018 5:41:16 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
    ERROR: Cannot add or update a child row: a foreign key constraint fails (`prueba`.`user`, CONSTRAINT `fk_user_account` FOREIGN KEY (`pk_account$user`) REFERENCES `account` (`id`))
    Jun 04, 2018 5:41:16 PM org.hibernate.internal.ExceptionMapperStandardImpl mapManagedFlushFailure
    ERROR: HHH000346: Error during managed flush [org.hibernate.exception.ConstraintViolationException: could not execute statement]
    Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement
        at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:149)
        at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:157)
        at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:164)
        at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1460)
        at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:511)
        at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3278)
        at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2474)
        at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:473)
        at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:178)
        at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:39)
        at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:271)
        at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:98)
        at com.espiritware.pruebaOneToOne.App.main(App.java:32)
    Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
        at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:59)
        at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
        at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111)
        at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:97)
        at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:178)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3136)
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3651)
        at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:90)
        at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604)
        at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:478)
        at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:356)
        at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
        at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1454)
        ... 9 more
    Caused by: java.sql.SQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails (`prueba`.`user`, CONSTRAINT `fk_user_account` FOREIGN KEY (`pk_account$user`) REFERENCES `account` (`id`))
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:115)
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:95)
        at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
        at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:960)
        at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1116)
        at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1066)
        at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1396)
        at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1051)
        at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:175)
        ... 17 more
我期望:

  • 从生成器获取ID,在帐户上设置它
  • 持续帐户
  • 在用户上设置帐户ID
  • 持久用户
  • 为什么上述情况不会发生?有没有办法像我预期的那样工作

    但是,如果我手动将id分配给用户,则不会出现问题:

    public static void main( String[] args )
    {
        SessionFactory sessionFactory;
        Configuration configuration= new Configuration();
        configuration.configure();
        sessionFactory=configuration.buildSessionFactory();
        Session session= sessionFactory.openSession();
        session.beginTransaction();
        Account account= new Account();
        account.setEmail("new@gmail.com");
    
        session.persist(account);
    
        User user= new User();
        user.setUserId(account.getAccountId());
        user.setIdentificationNumber("11462727272");
        account.setUser(user);
    
        session.persist(account);
        session.getTransaction().commit();
    
    }
    

    如果有人能给你一个解释,我将不胜感激。我希望在不进行手动分配的情况下执行此操作,保持单向关系

    JPA规范表明您不应再将
    @PrimaryKeyJoinColumn
    用于
    @OneToOne
    映射。由于
    用户
    主键由
    帐户
    确定,您可以尝试双向一对一并使用“派生标识”:


    第2.4.1节中讨论了派生身份(带有示例)。

    您能否在最后一句中添加指向JPA 2.2规范PDF的链接/url?
    @Entity
    @Table(name="account")
    @Getter
    @Setter
    public class Account implements Serializable{
        private static final long serialVersionUID = 1L;
    
        @Id
        @Column(name="id")
        @GeneratedValue(strategy= GenerationType.AUTO, generator="native")
        @GenericGenerator(name = "native", strategy = "native")
        private int accountId;
    
        @Column(name="email")
        private String email;
    
        @OneToOne(cascade = CascadeType.ALL, mappedBy="account")
        private User user;
    }
    
    @Entity
    @Table(name="user")
    @Getter
    @Setter
    public class User implements Serializable {
        private static final long serialVersionUID = 1L;
    
        @Id
        @Column(name="pk_account$user")
        private int userId;
    
        @OneToOne
        @MapsId
        private Account account;
    
        @Column(name="identification_number")
        private String identificationNumber;
    }