Hibernate 注解 - 不区分大小写 UniqueConstraint

发布于 2024-09-29 06:17:00 字数 229 浏览 0 评论 0原文

我有一个带有以下注释的实体:

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

是否可以使 UniqueConstraint 不区分大小写?我们正在使用 PostgreSQL。

I have an entity annotated with the following:

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

Is it possible to make the UniqueConstraint case insensitive? We are using PostgreSQL.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

撩人痒 2024-10-06 06:17:00

我建议从不同的角度解决这个问题:

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

    @NotEmpty
    @Column(可为空 = false)
    私有字符串 lcname;
    
  2. 更改您设置为注释的约束以使用新字段:

    @Entity
    @Table(uniqueConstraints={@UniqueConstraint(columnNames={"lcname"})})
    公共类组件扩展模型{
        ...
    }
    
  3. 修改名称设置器以将 lcname 设置为客户端提供的原始名称的小写

    public void setName(字符串名称) {
        this.name = 名称;
        this.lcname = name.toLowerCase();
    }
    

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

I would suggest attacking this problem from a different angle:

  1. add a new column, internal one, call it lcname (stands for lower-cased name)

    @NotEmpty
    @Column(nullable = false)
    private String lcname;
    
  2. change the constraint you set as annotation to use the new field instead :

    @Entity
    @Table(uniqueConstraints={@UniqueConstraint(columnNames={"lcname"})})
    public class Component extends Model {
        ...
    }
    
  3. modify the name setter to also set lcname with a lower case of the original name provided by the client

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

That's it. Every time the entity will be persisted, also a lower cased name will be saved. That way if you save "A" you'll have a record with lcname = "a" saved, and next time you try to save an entity with name "a" the operation will fail due to the constraint on lcname
The change is completely transparent to anyone who fetches an entity from the database since lcname is private and there is no getter for it, while the original getName will return the original name as provided initially by the client who created it.

独自唱情﹋歌 2024-10-06 06:17:00

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

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

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

如果您想依靠 Hibernate 的 hbm2ddl 工具来生成架构并且仍然创建该索引,我能想到的唯一选择是利用 import.sql 功能。来自 鹿特丹 JBug 和 Hibernate 的 import.sql 博客文章:

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

Hibernate 有一个巧妙的小功能
记录严重不足并且
未知。您可以执行 SQL 脚本
SessionFactory 创建期间
就在数据库模式之后
生成以全新方式导入数据
数据库。您只需要添加一个文件
在类路径中命名为 import.sql
root 并设置 create
create-drop 作为您的
hibernate.hbm2ddl.auto 属性。

我用它来进行 Hibernate 搜索
既然我已经开始行动了
查询章节。它初始化我的
数据库包含一组新数据
我的单元测试。 JBoss Seam 也使用它
各种例子中有很多。
import.sql 是一个非常简单的功能
但有时非常有用。记住
SQL 可能依赖于
你的数据库(啊可移植性!)。

#import.sql 文件
从产品中删除
插入产品(PROD_ID、ASIN、TITLE、PRICE、IMAGE_URL、DESCRIPTION)值('1'、'630522577X'、'My Fair Lady'、19.98、'630522577X.jpg'、'My Fair blah blah...') ;
插入产品(PROD_ID、ASIN、TITLE、PRICE、IMAGE_URL、DESCRIPTION)值('2'、'B00003CXCD'、'罗马假日'、12.98、'B00003CXCD.jpg'、'我们可以争论等等');

有关此内容的更多信息
功能,请查看 Eyal 的博客 (更新了死链接的位置),他
写了一篇关于它的好小文章。
如果您想添加其他内容,请记住
数据库对象(索引、表和
等等),您还可以使用
辅助数据库对象
功能。

With PostgreSQL, you would indeed do something like this to implement your requirement:

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

But there is to my knowledge no way to achieve this using annotations.

The only option I can think of if you want to rely on Hibernate's hbm2ddl tool to generate the schema and still have that index created would be to leverage the import.sql feature. From the Rotterdam JBug and Hibernate's import.sql blog post:

import.sql: easily import data in your unit tests

Hibernate has a neat little feature
that is heavily under-documented and
unknown. You can execute an SQL script
during the SessionFactory creation
right after the database schema
generation to import data in a fresh
database. You just need to add a file
named import.sql in your classpath
root and set either create or
create-drop as your
hibernate.hbm2ddl.auto property.

I use it for Hibernate Search in
Action now that I have started the
query chapter. It initializes my
database with a fresh set of data for
my unit tests. JBoss Seam also uses it
a lot in the various examples.
import.sql is a very simple feature
but is quite useful at time. Remember
that the SQL might be dependent on
your database (ah portability!).

#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');

For more information about this
feature, check Eyal's blog (Updated Location for dead link), he
wrote a nice little entry about it.
Remember if you want to add additional
database objects (indexes, tables and
so on), you can also use the
auxiliary database objects
feature.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文