NHibernate 4.1.1.4000/Oracle 12c - 使用“GENERATED ALWAYS”标识列

时间:2017-04-06 19:12:39

标签: c# oracle nhibernate

为这种情况找到合适的映射咒语有点困难。

我有一个Oracle数据库,其中包含一系列包含如下定义的标识列的表:

"ID" NUMBER GENERATED ALWAYS AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 NOCACHE  NOORDER  NOCYCLE  NOT NULL ENABLE

我的模型定义如下:

public class MyModel
{
    public virtual decimal Id { get; set; }
    public virtual string SomeProperty { get; set; }

}

像这样映射:

public class MyModelMap : ClassMapping<MyModel> {

    public MyModelMap() {
        Schema("OWNER");
        Lazy(true);
        Id(x => x.Id, map =>
        {
            map.Generator(Generators.SequenceIdentity, gmap => gmap.Params(new {sequence = "MySequenceName" }));
        }); 

        Property(x => x.SomeProperty, map => { map.NotNullable(true); map.Length(2); });

    }
}

当我尝试用这种方式映射`Session.Save(myModelObject)'时,NHibernate会生成这个:

INSERT INTO OWNER.MyModel
            (Id,
             SomeProperty)
VALUES      (OWNER.MySequenceName.nextval,
             'AA' /* :p0 */)
returning Id into :nhIdOutParam

数据库响应:

  

错误:ORA-32795:无法插入生成的始终标识列无法执行命令:INSERT INTO ...

这就像我已经能够通过NH在这些表中插入新记录一样接近。我也试过了其他几台发电机。例如,使用 Generators.Sequence导致像这样的INSERT ......

INSERT INTO OWNER.MyModel
            (SomeProperty, Id)
VALUES      ('AA' /* :p0 */, 50 /* :p1 */)
returning Id into :nhIdOutParam

...与数据库产生相同的错误(与Native,Sequence和EnhancedSequence Generators相同)。 Id每次都包含在INSERT中,要么具有特定值(按序列),要么对序列进行.nextval调用,当然,数据库告诉我我不允许这样做那。我无法找到一种方法来阻止NH尝试在Oracle中设置Id,从而让DB在INSERT上设置它。我在SQL Server中有类似的映射表,使用Identity Generator - NH不会尝试为这些表传递Id并且它们工作正常。

那么,我如何告诉NHibernate不要在它生成的INSERT中包含Id列?

我尝试设置map.Access(Accessor.ReadOnly);以防止这种情况发生,但是,除了SequenceIdentity Generator之外,导致NH无法通过以下投诉产生INSERT:

  

{“MyModel实例的标识符从54更改为0”}

(我的猜测 - NH正如预期的那样从数据库序列中获取下一个Id,但显然对于具有默认值0的实体Id存在问题。它指责我改变它,但我感觉

我可以继续列出我尝试过的所有内容,但希望我已经为比我更聪明的人提供了足够的信息来建立一些建议。提前谢谢!

1 个答案:

答案 0 :(得分:0)

NHibernate目前不support identity columns with Oracle

改为使用序列。

否则,尝试从Oracle12cDialect派生,覆盖SupportsIdentityColumns以返回true,覆盖适合Oracle的其他身份相关属性/方法,配置应用程序以使用新方言,地图您使用Identity生成的ID,并对其进行测试。

有关详细信息,请参阅Dialect标识区域。如果您能够实施身份支持,欢迎PR 在Hibernate方面,它看起来已实现,如果这可以帮助您使用NHibernate实现它,请参阅here