我正在尝试编写一个方法,它将返回一个基于唯一但非主键的Hibernate对象.如果实体已存在于数据库中,我想返回它,但如果不存在,我想创建一个新实例并在返回之前保存它.
更新:让我澄清一下,我正在编写的应用程序基本上是输入文件的批处理器.系统需要逐行读取文件并将记录插入数据库.文件格式基本上是我们模式中几个表的非规范化视图,所以我要做的是解析父记录,或者将其插入到db中,这样我就可以得到一个新的合成密钥,或者如果它已经存在则选择它.然后我可以在其他表中添加其他关联记录,这些表具有返回该记录的外键.
这很棘手的原因是每个文件需要完全导入或根本不导入,即为给定文件完成的所有插入和更新应该是一个事务的一部分.如果只有一个进程正在执行所有导入,这很容易,但是如果可能的话,我想在多个服务器上解决这个问题.由于这些约束,我需要能够保留在一个事务中,但是处理已经存在记录的异常.
父记录的映射类如下所示:
@Entity
public class Foo {
@Id
@GeneratedValue(strategy = IDENTITY)
private int id;
@Column(unique = true)
private String name;
...
}
Run Code Online (Sandbox Code Playgroud)
我最初尝试编写此方法的方法如下:
public Foo findOrCreate(String name) {
Foo foo = new Foo();
foo.setName(name);
try {
session.save(foo)
} catch(ConstraintViolationException e) {
foo = session.createCriteria(Foo.class).add(eq("name", name)).uniqueResult();
}
return foo;
}
Run Code Online (Sandbox Code Playgroud)
问题是当我正在寻找的名称存在时,调用uniqueResult()会抛出org.hibernate.AssertionFailure异常.完整的堆栈跟踪如下:
org.hibernate.AssertionFailure: null id in com.searchdex.linktracer.domain.LinkingPage entry (don't flush the Session after an exception occurs)
at org.hibernate.event.def.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:82) [hibernate-core-3.6.0.Final.jar:3.6.0.Final]
at org.hibernate.event.def.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:190) [hibernate-core-3.6.0.Final.jar:3.6.0.Final]
at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:147) [hibernate-core-3.6.0.Final.jar:3.6.0.Final]
at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:219) [hibernate-core-3.6.0.Final.jar:3.6.0.Final]
at …Run Code Online (Sandbox Code Playgroud) 我正在尝试为当前在LDAP存储中的主机数据提出PostgreSQL架构.部分数据是机器可以拥有的主机名列表,该属性通常是大多数人用来查找主机记录的关键.
我想将这些数据移动到RDBMS的一件事是能够在hostname列上设置唯一性约束,以便无法分配重复的主机名.如果主机只能有一个名称,这将很容易,但由于它们可以有多个名称,因此它更复杂.
我意识到这样做的完全规范化的方法是让一个主机名表的外键指向hosts表,但是我想避免让每个人都需要为最简单的查询做连接:
select hostnames.name,hosts.*
from hostnames,hosts
where hostnames.name = 'foobar'
and hostnames.host_id = hosts.id;
Run Code Online (Sandbox Code Playgroud)
我认为使用PostgreSQL数组可以为此工作,它们肯定使简单的查询变得简单:
select * from hosts where names @> '{foobar}';
Run Code Online (Sandbox Code Playgroud)
但是,当我在hostnames属性上设置唯一性约束时,它当然会将整个名称列表视为唯一值而不是每个名称.有没有办法让每个名称在每一行都是唯一的?
如果没有,有没有人知道另一种更有意义的数据建模方法?
UNIQUE一列或一组列上指定的约束是否会以任何方式影响Postgres DB的写入性能?它内部如何运作?
我的意思是,它是否在插入新记录时执行独特的检查?如果是,它是如何做到的,它是否对数据库中已存在的重复值进行线性搜索?在这种情况下,它被认为会影响性能,即写入/插入性能更差的唯一约束更多?这是真的吗?
我有简单的类别表.类别可以具有父类别(par_cat列),如果它是主类别,则为null,并且具有相同的父类别,不应该有2个或更多具有相同名称或URL的类别.
该表的代码:
CREATE TABLE IF NOT EXISTS `categories` (
`id` int(10) unsigned NOT NULL,
`par_cat` int(10) unsigned DEFAULT NULL,
`lang` varchar(2) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'pl',
`name` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`url` varchar(120) COLLATE utf8_unicode_ci NOT NULL,
`active` tinyint(3) unsigned NOT NULL DEFAULT '1',
`accepted` tinyint(3) unsigned NOT NULL DEFAULT '1',
`priority` int(10) unsigned NOT NULL DEFAULT '1000',
`entries` int(10) unsigned NOT NULL DEFAULT '0',
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL …Run Code Online (Sandbox Code Playgroud) 我使用Entity Framework来访问我的SQL数据.我在数据库模式中有一些约束,我想知道如何处理由这些约束引起的异常.
例如,在两个用户尝试同时向DB添加(几乎)相同的实体的情况下,我得到以下异常.
System.Data.UpdateException
"An error occurred while updating the entries. See the InnerException for details."
(inner exception) System.Data.SqlClient.SqlException
"Violation of UNIQUE KEY constraint 'Unique_GiftId'. Cannot insert duplicate key in object 'dbo.Donations'.\r\nThe statement has been terminated."
Run Code Online (Sandbox Code Playgroud)
如何正确捕获此特定异常?
脏的解决方案:
catch (UpdateException ex)
{
SqlException innerException = ex.InnerException as SqlException;
if (innerException != null && innerException.Message.StartsWith("Violation of UNIQUE KEY constraint 'Unique_GiftId'"))
{
// handle exception here..
}
else
{
throw;
}
}
Run Code Online (Sandbox Code Playgroud)
现在虽然这种方法有效,但它有一些缺点:
你知道更好的解决方案吗?感谢所有反馈..
注意:我不想在应用程序层中手动编写约束,我想将它们放在数据库中.
sql sql-server entity-framework constraints unique-constraint
在我的一个PostgreSQL表中,我有一组两个字段,将在表中定义为唯一,但在选择数据时也将一起使用.鉴于此,我是否只需要定义一个UNIQUE INDEX,或者除了UNIQUE INDEX之外还应该指定一个INDEX吗?
这个?
CREATE UNIQUE INDEX mytable_col1_col2_idx ON mytable (col1, col2);
Run Code Online (Sandbox Code Playgroud)
或这个?
CREATE UNIQUE INDEX mytable_col1_col2_uidx ON mytable (col1, col2);
CREATE INDEX mytable_col1_col2_idx ON mytable (col1, col2);
Run Code Online (Sandbox Code Playgroud) 我有两个具有HABTM关系的模型 - 用户和角色.
我想在join(users_roles表)中添加一个唯一性约束,表示user_id和role_id必须是唯一的.在Rails中,看起来像:
validates_uniqueness_of :user, :scope => [:role]
Run Code Online (Sandbox Code Playgroud)
当然,在Rails中,我们通常没有一个模型来表示HABTM关联中的连接关系.
所以我的问题是添加约束的最佳位置在哪里?
我有一个unique_together定义为3个字段的模型是唯一的:
class MyModel(models.Model):
clid = models.AutoField(primary_key=True, db_column='CLID')
csid = models.IntegerField(db_column='CSID')
cid = models.IntegerField(db_column='CID')
uuid = models.CharField(max_length=96, db_column='UUID', blank=True)
class Meta(models.Meta):
unique_together = [
["csid", "cid", "uuid"],
]
Run Code Online (Sandbox Code Playgroud)
现在,如果我尝试MyModel使用现有的csid + cid + uuid组合保存实例,我会得到:
IntegrityError: (1062, "Duplicate entry '1-1-1' for key 'CSID'")
Run Code Online (Sandbox Code Playgroud)
哪个是对的.但是,有没有办法自定义该密钥名称?(CSID在这种情况下)
换句话说,我可以为列出的约束提供名称unique_together吗?
据我了解,文档中未涉及此内容.
我有模型AppVersion,App& DeployApp。在AppVersion 模型中,用户可以将 APK 文件上传到文件系统。我使用的pre_save信号,以防止同样的上传APK文件version_code的具体App是这样的:
@receiver(pre_save, sender=AppVersion)
def prevent_duplicate_version_code(sender, instance, **kwargs):
qs = AppVersion.objects.filter(app_uuid=instance.app_uuid, version_code=instance.version_code)
if qs.exists():
raise FileExistsError("Version code has to be unique for a specific app")
Run Code Online (Sandbox Code Playgroud)
这个信号做我想要的,除了当我试图在 bridge-table 中创建一个对象时它也会引发错误DeployApp。
# models.py
class App(models.Model):
app_uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, db_index=True)
app_name = models.CharField(max_length=100)
class AppVersion(models.Model):
app_version_uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, db_index=True)
app_uuid = models.ForeignKey(App, on_delete=models.CASCADE, related_name='app_versions')
app_version_name = models.CharField(max_length=100)
version_code = models.IntegerField(blank=True, null=True, …Run Code Online (Sandbox Code Playgroud) 我在表格中有一个约束
CREATE TABLE "USERSAPPLICATIONS" (
"USERID" NUMBER NOT NULL ,
"APPLICATIONNAME" VARCHAR2 (30) NOT NULL ,
CONSTRAINT "PK_USERSAPPLICATIONS" PRIMARY KEY ("USERID","APPLICATIONNAME")
)
/
Run Code Online (Sandbox Code Playgroud)
两周前我修改了表,添加了一些列,删除了约束"PK_USERSAPPLICATIONS"并添加了一个代理键.我可以在Oracle SQL Developer中看到约束PK_USERSAPPLICATIONS不再存在.
无论如何,当我尝试使用相同的userid/applicationName组合添加两个条目时,我收到错误
SQL Error: ORA-00001: unique constraint (ACCOUNTMP1.PK_USERSAPPLICATIONS) violated
00001. 00000 - "unique constraint (%s.%s) violated"
*Cause: An UPDATE or INSERT statement attempted to insert a duplicate key.
For Trusted Oracle configured in DBMS MAC mode, you may see
this message if a duplicate entry exists at a different level.
*Action: Either remove the unique …Run Code Online (Sandbox Code Playgroud) postgresql ×3
sql ×3
django ×2
mysql ×2
python ×2
arrays ×1
constraints ×1
database ×1
hibernate ×1
indexing ×1
java ×1
ldap ×1
ora-00001 ×1
oracle ×1
performance ×1
sql-server ×1
unique-index ×1
unique-key ×1
upsert ×1