在NHibernate中处理异常的最佳实践是什么?
我有一个带有以下内容的SubjectRepository:
public void Add(Subject subject)
{
using (ISession session = HibernateUtil.CurrentSession)
using (ITransaction transaction = session.BeginTransaction())
{
session.Save(subject);
transaction.Commit();
}
}
Run Code Online (Sandbox Code Playgroud)
单元测试如下:
[Test]
public void TestSaveDuplicate()
{
var subject = new Subject
{
Code = "En",
Name = "English"
};
_subjectRepository.Add(subject);
var duplicateSubject = new Subject
{
Code = "En",
Name = "English1"
};
_subjectRepository.Add(duplicateSubject);
}
Run Code Online (Sandbox Code Playgroud)
我已经到了处理单元测试产生的错误并且有点卡住的问题.这会按预期失败,但是使用GenericADOException时,我期待一个ConstraintViolationException或类似的东西(在数据库级别的主题代码上存在唯一性约束).
ADOException包含一个MySQL Exception,它有一个明智的错误消息,但我不想通过抛出内部异常来开始破解封装.特别是因为MySQL没有最终确定为该项目的后端.
理想情况下,我希望能够捕获异常并在此时向用户返回合理的错误.是否有任何记录的最佳实践方法来处理NHibernate Exceptions并向用户报告出错的原因以及原因?
谢谢,
马特
我还在学习hibernate/hql的过程中,我有一个问题是半最佳实践问题/半理智检查.
假设我有一个A类:
@Entity
public class A
{
@Id @GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@Column(unique=true)
private String name = "";
//getters, setters, etc. omitted for brevity
}
Run Code Online (Sandbox Code Playgroud)
我想强制保存的每个A实例都有一个唯一的名称(因此是@Column注释),但我也希望能够处理已经保存了具有该名称的A实例的情况.我看到两种方法:
1)我可以捕获可能在session.saveOrUpdate()调用期间抛出的org.hibernate.exception.ConstraintViolationException并尝试处理它.
2)在调用session.saveOrUpdate()之前,我可以在DAO中查询已经具有该名称的A的现有实例.
现在我倾向于接近方法2,因为在方法1中我不知道如何以编程方式找出违反了哪个约束(A中还有其他一些独特的成员).现在我的DAO.save()代码看起来大致如下:
public void save(A a) throws DataAccessException, NonUniqueNameException
{
Session session = sessionFactory.getCurrentSession();
try
{
session.beginTransaction();
Query query = null;
//if id isn't null, make sure we don't count this object as a duplicate
if(obj.getId() == null)
{
query = session.createQuery("select count(a) from A a where a.name = :name").setParameter("name", obj.getName());
}
else …Run Code Online (Sandbox Code Playgroud) 我一直在:
SQL错误:错误:无法创建唯一索引"service_import_checksum_key"DETAIL:密钥(校验和)=()是重复的.
声明:
ALTER TABLE"public"."service_import"ADD CONSTRAINT"service_import_checksum_key"UNIQUE("checksum")
但这种约束并不重复.在整个数据库中没有任何其他类似的限制,我不知道为什么它一直坚持它是重复的.我假设这是我在这里缺少的一些奇怪的postgres细微差别.
我究竟做错了什么?
表转储:
--
-- PostgreSQL database dump
--
SET statement_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = off;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET escape_string_warning = off;
SET search_path = public, pg_catalog;
SET default_tablespace = '';
SET default_with_oids = false;
--
-- Name: service_import; Type: TABLE; Schema: public; Owner: cvs_tar; Tablespace:
--
CREATE TABLE service_import (
id integer NOT NULL,
name character varying(32) NOT NULL,
importfile character varying(64) …Run Code Online (Sandbox Code Playgroud) 我是Hibernate和DBs的新手,所以请原谅这个基本问题.
我正在使用DIS协议,特别是DIS的Open-DIS实现.在DIS中,每个EntityStatePdu(包含模拟中实体的状态)都有一个EntityId对象,一个3个整数的元组.我想将此对象用作自然ID,并保持标准的代理ID.我的问题是我无法弄清楚如何确保DB确定给定的EntityId已经存在并使用该EntityId的主键作为EntityStatePdu中的外键.
换句话说,假设我有两个EntityStatePdus,EntityID(1,2,3); 即我们有来自同一实体的两个更新.我想要的东西如下:
表:
entity_id
pk site app entity
0 1 2 3
entity_state_pdu
pk entity_id_fk timestamp
0 0 1
1 0 2
Run Code Online (Sandbox Code Playgroud)
以下是我正在测试的简化类:
@Entity
public class TestEntity {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@NaturalId
@ManyToOne(cascade = CascadeType.ALL)
private TestId naturalId;
public Long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public TestId getNaturalId() {
return naturalId;
}
public void setNaturalId(TestId naturalId) {
this.naturalId = naturalId;
}
}
Run Code Online (Sandbox Code Playgroud)
和
@Entity
public …Run Code Online (Sandbox Code Playgroud) 我有一种情况,表有三列ID,值和状态.对于不同的ID,应该只有一个值为1的状态,并且应该允许ID具有多于一个值为0的状态.唯一键将阻止ID具有多于一个状态(0或1).
有没有办法解决这个问题,可能使用约束?
谢谢
sql sql-server-2005 unique check-constraints unique-constraint
我收到一个我无法理解的错误.错误非常简单:
ORA-00001: unique constraint (*schema*.*xyz_constraint*) violated
Run Code Online (Sandbox Code Playgroud)
然而,造成我困惑的是事实上似乎不存在这样的约束.它当然没有在桌子上定义; 有问题的DB几乎没有定义参照完整性,我插入数据的特定表没有定义键.
对于它的价值,我无法在数据库中的任何位置找到约束:
select *
from all_constraints
where constraint_name like '%xyz_constraint%'
Run Code Online (Sandbox Code Playgroud)
有什么我可以忽略的吗?谢谢.
我需要在PostgreSQL中使用这些独特的约束
CREATE UNIQUE INDEX favorites_3col_uni_idx
ON favorites (user_id, menu_id, recipe_id)
WHERE menu_id IS NOT NULL;
CREATE UNIQUE INDEX favorites_2col_uni_idx
ON favorites (user_id, recipe_id)
WHERE menu_id IS NULL;
Run Code Online (Sandbox Code Playgroud)
我在JPA中注释的第一个:
@Table(uniqueConstraints= {
@UniqueConstraint(name="favorites_3col_uni_idx", columnNames = {"user_id", "menu_id", "recipe_id"})
})
Run Code Online (Sandbox Code Playgroud)
但是,有可能在JPA中注释第二个唯一索引吗?
谢谢.
我们有一个名为Organization的实体,我们使用UniqueConstraints-bundle.我们有一个名为NetName的属性,它是一个UniqueConstraint和一个自动生成的Id.
由于这是不必要的,我们希望将NetName属性用作Id.因此,我们不需要UniqueConstraints来知道它是唯一的,并且当我们拥有NetName时能够使用Load也能获得好处.
在将它用作Id之前,我们需要稍微清理一下我们的网络名,因此我们创建了一个名为TempUniqueNetName的新临时属性,该属性现在保存的值为:
"organizations/"+ CleanupId(this.NetName)
Run Code Online (Sandbox Code Playgroud)
所以我们现在准备好将该值移动到我们的Id.但我们无法让它发挥作用.我们的问题是,在下面的PatchRequest中,我们最终得到了一个名为Id的新属性,但是acctual Id仍然具有相同的值(见截图).是否有更好(正确)的方法来更改Id的值?
实体:
class Organization {
public string Id { get; set; }
[UniqueConstraint]
public string NetName { get; set; }
public string TempUniqueNetName{ get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我们想做这样的事情:
_documentStore.DatabaseCommands.UpdateByIndex(typeof(Organizations).Name,
new IndexQuery(),
new[]
{
new PatchRequest()
{
Type = PatchCommandType.Rename,
Name = "TempUniqueNetName",
Value = new RavenJValue("Id")
}
});
Run Code Online (Sandbox Code Playgroud)

我有一个用户共享模型,如下所示:
class Share( models.Model ):
sharer = models.ForeignKey(User, verbose_name=_("Sharer"), related_name='sharer')
receiver = models.ForeignKey(User, verbose_name=_("Receiver"), related_name='receiver')
class Meta:
unique_together = ( ("sharer", "receiver"), ("receiver", "sharer") )
Run Code Online (Sandbox Code Playgroud)
我想为sharer(S)和receiver(R)保存单个对象(顺序与RS或SR无关).但以上unique_together将无法满足此要求; 假设RS在数据库中,然后如果我保存SR,我将不会得到验证.为此,我为Share模型编写了自定义唯一验证.
def validate_unique(
self, *args, **kwargs):
super(Share, self).validate_unique(*args, **kwargs)
if self.__class__.objects.filter( Q(sharer=self.receiver, receiver=self.sharer) ).exists():
raise ValidationError(
{
NON_FIELD_ERRORS:
('Share with same sharer and receiver already exists.',)
}
)
def save(self, *args, **kwargs):
# custom unique validate
self.validate_unique()
super(Share, self).save(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
此方法在正常使用中正常工作.
问题: 我有一个匹配的算法,它获取共享和接收者的请求并保存共享对象(SR或RS),然后几乎同时发送响应(共享对象).因为我检查与查询重复(没有数据库级别)需要时间,所以最后我有2个对象SR和RS.
我想要一些解决方案,对于共享者S和接收者RI只能保存单个共享对象,SR或RS否则会得到一些验证错误(如数据库的IntegrityError).
Django = 1.4,Database = Postgresql
我有一个看起来像这样的表:
ClientId FloorNum BedNum IsActive
11 2 212 1
12 2 214 0
12 2 214 1
13 2 215 0
13 2 215 0
13 2 215 0
13 2 215 0
13 2 215 1
12 2 215 1
Run Code Online (Sandbox Code Playgroud)
如您所见,FloorNum/BedNum组合2/215有两行,其中IsActive等于1.这不可能发生.
另一方面,一个FloorNum/BedNum组合可以有许多行,其中IsActive等于0.
如何向表中添加约束,以便FloorNum/BedNum组合只能有一行IsActive = 1?
任何帮助表示赞赏.
postgresql ×3
sql ×3
hibernate ×2
java ×2
constraints ×1
database ×1
django ×1
exception ×1
jpa ×1
nhibernate ×1
oracle ×1
oracle10g ×1
ravendb ×1
sanity-check ×1
sql-server ×1
t-sql ×1
unique ×1
unique-key ×1
validation ×1