【问题标题】:Unable to create unique key constraint无法创建唯一键约束
【发布时间】:2014-08-09 18:52:45
【问题描述】:

我正在创建一个简单的实体并尝试将其持久化到 Oracle 数据库。这是我的实体:

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

@Entity
@Table(name = "TBL_FLIGHT", uniqueConstraints = @UniqueConstraint(name = "flight_number", columnNames = {
        "comp_prefix", "flight_number" }))
public class Flight implements Serializable {
    @Id 
    private Long id;
    private String companyPrefix;
    private String number;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public void setCompanyPrefix(String companyPrefix) {
        this.companyPrefix = companyPrefix;
    }

    public void setNumber(String number) {
        this.number = number;
    }   

    @Column(name = "comp_prefix")
    public String getCompanyPrefix() {
        return companyPrefix;
    }

    @Column(name = "flight_number")
    public String getNumber() {
        return number;
    }
}

这是我的 Java 类,它创建该实体的一个实例并使用 Hibernate 将其保存到数据库:

public class AppTest{

    public static void main(String[] args) {

        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();

        Flight flight = new Flight();
        flight.setCompanyPrefix("prefix");;
        flight.setNumber("100");
        flight.setId(1L);
        session.save(flight);

        session.getTransaction().commit();          

        HibernateUtil.getSessionFactory().close();
    }
}

当我运行这个程序时,我得到一个异常:

Caused by: org.hibernate.AnnotationException: Unable to create unique key constraint (comp_prefix, flight_number) on table TBL_FLIGHT: database column 'comp_prefix', 'flight_number' not found. Make sure that you use the correct column name which depends on the naming strategy in use (it may not be the same as the property name in the entity, especially for relational types)
    at org.hibernate.cfg.Configuration.buildUniqueKeyFromColumnNames(Configuration.java:1682)
    at org.hibernate.cfg.Configuration.buildUniqueKeyFromColumnNames(Configuration.java:1614)
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1450)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1844)

请帮助我在此代码中出错的地方。我正在使用Hibernate-4.3.6

更新:这是我的hibernate配置文件,表是由hibernate自己生成的:

<session-factory>

    <!-- Database connection settings -->
    <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
    <property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:XE</property>
    <property name="hibernate.connection.username">myuser</property>
    <property name="hibernate.connection.password">mypasswd</property>
    <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>

    <!-- JDBC connection pool (use the built-in) -->
    <property name="connection.pool_size">1</property>

    <!-- Enable Hibernate's automatic session context management -->
    <property name="current_session_context_class">thread</property>

    <!-- Disable the second-level cache -->
    <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>

    <!-- Echo all executed SQL to stdout -->
    <property name="show_sql">true</property>

    <!-- Drop and re-create the database schema on startup -->
    <property name="hbm2ddl.auto">update</property>

    <mapping class="org.hibernate.tutorial.Flight" />
</session-factory>

如果可能的话,请给我推荐一个 Hibernate-4.3 的好资源,因为 online document 对于像我这样的初学者来说不是一个好资源。

【问题讨论】:

  • 能否请您发布您的表的 DDL?
  • @Teh,我已经配置 hibernate 在我运行程序时为我生成表,我已经将 hibernate.cfg.xml 文件添加到我的帖子中,请检查。

标签: java hibernate


【解决方案1】:

我遇到了同样的错误,通过显式设置@Column(name = "field_name") 解决了 到@UniqueConstraint中使用的属性。

【讨论】:

    【解决方案2】:

    当我尝试在 A 类的“a_id”和“b_id”列上创建唯一约束并且我没有用 @ManyToOne 注释 B 时,问题出现在我身上,因此 Hibernate 对“b_id”列一无所知"(作为 B 类的外键):

       @Entity
       @Table(uniqueConstraints = { @UniqueConstraint(columnNames = { "a_id", "b_id" }) })
       Class A {
          @Id
          a_id;
    
          // @ManyToOne was not annotated
          B b;
       }
    
       @Entity
       Class B {
          @Id
          b_id
       }
    

    【讨论】:

      【解决方案3】:

      您正在使用字段访问策略(由@Id 注释确定)。将任何与 JPA 相关的注释放在每个字段的正上方,而不是 getter 属性

      作为 JPA 提供者,Hibernate 可以自省这两个实体属性 (实例字段)或访问器(实例属性)。默认情况下, @Id 注释的位置给出了默认的访问策略。 当放置在一个字段上时,Hibernate 将假定基于字段的访问。 放置在标识符 getter 上,Hibernate 将使用基于属性的 访问

      【讨论】:

        【解决方案4】:

        完整的错误文本是:

        原因:org.hibernate.AnnotationException:无法在表 TBL_FLIGHT 上创建唯一键约束(comp_prefix、flight_number):找不到数据库列“comp_prefix”、“flight_number”。确保使用正确的列名,这取决于所使用的命名策略(它可能与实体中的属性名称不同,尤其是关系类型)

        您很可能拼错了其中一个列名。

        【讨论】:

        • 列名注释是一样的。
        • 感谢 Bohemian,我已经用休眠配置文件更新了我的帖子。该表是由休眠本身生成的,并且根据我的实体,我使用了正确的列名。
        • 在字段级别而不是方法级别添加@Column 注释已经解决了这个问题。我按照hibernate在线文档准备了这个简单的程序。看来文档不完整或有一些错误,请您建议如何学习hibernate - 4.3?
        • 您的解决方案听起来很有用 - 将其作为答案发布,以便其他人受益(“回答您自己的问题”很好)。至于学习,我会从谷歌开始,但没有什么比经验更重要 - 尽可能多地使用它。
        猜你喜欢
        • 2015-09-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-04
        • 2011-05-28
        • 1970-01-01
        相关资源
        最近更新 更多