JPA提供者(Hibernate / Eclipselink)是否应该在单向一对一关系中设置唯一约束?

时间:2014-04-30 15:40:48

标签: hibernate jpa eclipselink

我开始学习JPA 2.1,现在我正在阅读关系。

JSR-338中定义了单向一对一关系,如下所示(第2.10.3.1节和第34节;单向OneToOne Relationshps")

  

以下映射默认值适用:

     
      
  • 实体A映射到名为A的表。
  •   
  • 实体B映射到名为B的表。
  •   
     

表A包含表B的外键。外键列   name形成为以下内容的串联:名称   实体财产或实体A的领域; " _"'的名字   表B中的主键列。外键列具有相同的列   键入表B的主键,并且有一个唯一的键约束   它

我的问题是外键列的唯一约束不存在,所以我想知道我的代码是否有问题。

这是我的代码:

第一个实体

@Entity
public class FootballPlayer {

    @Id
    private long id;

    @OneToOne
    private Ball ball;

    public FootballPlayer() {
    }

    public FootballPlayer(long id) {
        this.id = id;
    }

    public long getId() {
        return id;
    }

    public void setBall(Ball ball) {
        this.ball = ball;
    }

    public Ball getBall() {
        return ball;
    }
}

第二实体:

@Entity
public class Ball {

    @Id
    private long id;

    public Ball() {
    }

    public Ball(long id) {
        this.id = id;
    }

    public long getId() {
        return id;
    }
}

以下情况应该在我看来以异常结束:

EntityManagerFactory emf = Persistence.createEntityManagerFactory("pu");
EntityManager em = emf.createEntityManager();

FootballPlayer firstPlayer = new FootballPlayer(1L);
FootballPlayer secondPlayer = new FootballPlayer(2L);
Ball ball = new Ball(10L);

firstPlayer.setBall(ball);
secondPlayer.setBall(ball);

em.getTransaction().begin();
em.persist(ball);
em.persist(firstPlayer);
em.persist(secondPlayer);
em.getTransaction().commit();

em.close();
emf.close();

我正在使用Hibernate 4.3.0,在pom.xml中定义如下:

<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-core</artifactId>
  <version>4.3.0.Final</version>
</dependency>
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-entitymanager</artifactId>
  <version>4.3.0.Final</version>
</dependency>

内存数据库Derby 10.10.1.1:

<dependency>
  <groupId>org.apache.derby</groupId>
  <artifactId>derby</artifactId>
  <version>10.10.1.1</version>
</dependency>

persistence.xml中的持久性单元:

<persistence-unit name="pu">
  <provider>org.hibernate.ejb.HibernatePersistence</provider>

  <class>com.mprzybylak.minefields.jpa.relationships.onetoone.uni.Ball</class>
  <class>com.mprzybylak.minefields.jpa.relationships.onetoone.uni.FootballPlayer</class>

  <properties>
    <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
    <property name="javax.persistence.jdbc.url" value="jdbc:derby:memory:test;create=true" />
    <property name="javax.persistence.jdbc.user" value="APP" />
    <property name="javax.persistence.jdbc.password" value="APP" />             
    <property name="hibernate.show_sql" value="true" />
    <property name="hibernate.use_sql_comments" value="true"/>
    <property name="hibernate.hbm2ddl.auto" value="create" />
  </properties>

</persistence-unit>

我试图切换到eclipselink,但我仍然有这个问题。我使用了eclipselink 2.5.1

<dependency>
  <groupId>org.eclipse.persistence</groupId> 
  <artifactId>eclipselink</artifactId>
  <version>2.5.1</version>
</dependency>

使用以下持久性单元配置:

<persistence-unit name="pu" transaction-type="RESOURCE_LOCAL">

<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>com.mprzybylak.minefields.jpa.relationships.onetoone.uni.Ball</class>
<class>com.mprzybylak.minefields.jpa.relationships.onetoone.uni.FootballPlayer</class>

  <properties>
    <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
    <property name="javax.persistence.jdbc.url"value="jdbc:derby:memory:test;create=true" />
    <property name="javax.persistence.jdbc.user" value="APP" />
    <property name="javax.persistence.jdbc.password" value="APP" />

    <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
    <property name="eclipselink.logging.level.sql" value="FINE"/>
    <property name="eclipselink.logging.parameters" value="true"/>
  </properties>
</persistence-unit>

JPA的工作方式我认为只有当我在@JoinColumn(unique=true)类<{1}}类ball字段中添加FootballPlayer注释时才应该这样做

那么,我在代码中做错了吗?因为我很难相信,两个主要的JPA提供商都不遵守JPA规范。

2 个答案:

答案 0 :(得分:1)

我认为您发现了一个错误,它包括EclipseLink和Hibernate。我认为,规范的这一部分被忽略了。所以你应该报告错误。

PS:这也是JPA 2.0的要求。

答案 1 :(得分:0)

我也可以确认这个错误。我正在使用带有EclipseLink 2.0.0的Derby DB。问题在那里,我花了3个多小时试图找到我的代码有什么问题......显然没什么。