代码之家  ›  专栏  ›  技术社区  ›  Rich

休眠注释-不区分大小写的唯一约束

  •  7
  • Rich  · 技术社区  · 15 年前

    我有一个实体注释如下:

    @Entity
    @Table(uniqueConstraints={@UniqueConstraint(columnNames={"name"})})
    public class Component extends Model {
        ...
    }
    

    是否可以使唯一约束不区分大小写?我们正在使用PostgreSQL。

    2 回复  |  直到 8 年前
        1
  •  6
  •   Sebastiaan van den Broek    8 年前

    使用PostgreSQL,您确实需要这样做来实现您的需求:

    CREATE UNIQUE INDEX My_Index on Component (lower(name));
    

    但据我所知,没有办法用注释来实现这一点。

    如果你想依靠Hibernate我能想到的唯一选择 hbm2ddl 工具来生成模式,并且仍然创建索引 利用 import.sql 特征 . 来自 Rotterdam JBug and Hibernate's import.sql 博客帖子:

    import.sql:在单元测试中轻松导入数据

    冬眠有一个整洁的小特征 这是严重的文件不足和 未知。可以执行SQL脚本 在 SessionFactory 创造 在数据库模式之后 生成以导入新数据 数据库。你只需要添加一个文件 命名 导入.sql 在你的课堂上 根并设置 create create-drop 作为您的 hibernate.hbm2ddl.auto 属性。

    我用它来搜索冬眠 行动现在我已经开始了 查询章节。它初始化我的 具有新数据集的数据库 我的单元测试。JBoss Seam也使用它 在各种各样的例子中有很多。 导入.sql 是一个非常简单的功能 但在当时非常有用。记得 SQL可能依赖于 您的数据库(可移植性!).

    #import.sql file
    delete from PRODUCTS
    insert into PRODUCTS (PROD_ID, ASIN, TITLE, PRICE, IMAGE_URL, DESCRIPTION) values ('1', '630522577X', 'My Fair Lady', 19.98, '630522577X.jpg', 'My Fair blah blah...');
    insert into PRODUCTS (PROD_ID, ASIN, TITLE, PRICE, IMAGE_URL, DESCRIPTION) values ('2', 'B00003CXCD', 'Roman Holiday ', 12.98, 'B00003CXCD.jpg', 'We could argue that blah blah');
    

    有关此的详细信息 功能,检查 Eyal's blog ( Updated Location for dead link 他 写了一篇关于它的小文章。 如果您想添加其他 数据库对象(索引、表和 等等),你也可以使用 auxiliary database objects 功能。

        2
  •  10
  •   naXa stands with Ukraine    9 年前

    我建议从另一个角度来解决这个问题:

    1. 添加一个新列,内部列,称之为lcname(代表小写名称)

      @NotEmpty
      @Column(nullable = false)
      private String lcname;
      
    2. 将设置为注释的约束更改为使用新字段:

      @Entity
      @Table(uniqueConstraints={@UniqueConstraint(columnNames={"lcname"})})
      public class Component extends Model {
          ...
      }
      
    3. 修改名称设置器,以使用客户端提供的原始名称的小写字母设置lcname。

      public void setName(String name) {
          this.name = name;
          this.lcname = name.toLowerCase();
      }
      

    就这样。每次实体被持久化时,也会保存一个小写的名称。这样,如果保存“a”,则会保存lcname=“a”的记录,下次尝试保存名为“a”的实体时,由于lcname的约束,操作将失败。 对于从数据库中提取实体的任何人来说,更改都是完全透明的,因为lcname是私有的,没有getter,而原始getname将返回最初由创建它的客户机提供的原始名称。