【问题标题】:Hiberate problems, jdbc IDENTITY_INSERT is set to OFFHibernate问题,jdbc IDENTITY_INSERT设置为OFF
【发布时间】:2010-10-01 22:07:02
【问题描述】:

当我尝试通过休眠向 SQL Server 提交时出现 JDBC 错误

当 IDENTITY_INSERT 设置为 OFF 时,无法在表“报告”中插入标识列的显式值

我正在使用由 netbeans 生成的映射,其中包含,

<class name="orm.generated.Report" table="Report" schema="dbo" catalog="DatabaseName">
    <id name="id" type="int">
        <column name="ID" />
        <generator class="assigned" />
    </id>

在我看来它应该正确地进行身份插入。

知道如何解决这个问题吗?

编辑:
一些文档链接,供后人参考,
http://www.hibernate.org/hib_docs/v3/reference/en-US/html/mapping.html#mapping-declaration-id-generator
http://www.roseindia.net/hibernate/hibernateidgeneratorelement.shtml

【问题讨论】:

    标签: sql sql-server hibernate jdbc


    【解决方案1】:

    除非“IDENTITY_INSERT”设置为“ON”,否则您无法插入到 SQL Server 中的标识列。由于您的生成器类是“分配的”,Hibernate 假设您在保存对象之前在 Java 中为“id”设置了一个显式值,并且 Hibernate 可以直接将该值插入到数据库中。您需要:

    1. 选择不同的生成器类,例如“native”
    2. 将 IDENTITY_INSERT 设置为“开启”

    【讨论】:

    • 这有效,导致我进入另一个错误,但它有效,谢谢。
    • 澄清一下,我的意思是,通过解决这个问题,我发现了另一个问题。
    【解决方案2】:

    尝试将生成器类的类型从“分配”更改为“身份”,它对我有用

    【讨论】:

    • 谢谢。从@GeneratedValue(strategy = GenerationType.AUTO) 更改为@GeneratedValue(strategy = GenerationType.IDENTITY) 后解决了我的问题。
    【解决方案3】:

    这里有一些对我有用的东西。根据需要进行调整。

    @SuppressWarnings("deprecation")
    public static void saveWithOverwrittenId(Session session, Object entity) {
        String tableName = entity.getClass().getSimpleName();
        boolean identityInsertSetToOn = false;
        try {
            session.connection().createStatement().execute("SET IDENTITY_INSERT "+tableName+" ON");
            identityInsertSetToOn = true;
            session.beginTransaction();
            session.saveOrUpdate(entity);
            session.getTransaction().commit();
        } catch (SQLException e) {
            session.getTransaction().rollback();
            throw new RuntimeException(e);
        } finally {
            if (identityInsertSetToOn) {
                try {
                    session.connection().createStatement().execute("SET IDENTITY_INSERT "+tableName+" OFF");
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
    

    在我的例子中,SQL Server 表与实体类同名。对你来说,这可能不是真的。那么,一种解决方案是将表名作为参数询问。

    【讨论】:

    • 我有同样的需求,但我必须通过 JPA 来完成。由于某种原因,它不能通过 JPA 工作。我想通过 JPA 运行这个查询。你能帮忙吗?
    • @muasif80 我建议您创建一个新问题,具体询问(可能引用此代码并要求 JPA 等效项)。以这种方式解决问题的机会更大。
    • 是的,谢谢,我确实做到了,我找到了解决方案。然后我回答了我自己的问题。您可以在我的个人资料下找到该问题。
    【解决方案4】:

    改变生成器类的类型

    之前

    <id name="id" type="long">
            <column name="Id" />
            <generator class="assigned" />
        </id>
    

    之后

    <id name="id" type="long">
            <column name="Id" />
            <generator class="native" />
        </id>
    

    现在可以了!

    【讨论】:

      【解决方案5】:

      最好使用像 Integer 这样的包装类而不是原始 int。

      以你的代码为例

      <class name="orm.generated.Report" table="Report" schema="dbo" catalog="DatabaseName">
      <id name="id" type="java.lang.Integer">
          <column name="ID" />
          <generator class="assigned" />
      </id>
      

      【讨论】:

      • 在你的帖子中添加尽可能多的相关细节是一个很好的做法。因此,例如,您可以在此处添加代码示例。这将使您的答案更有价值;)
      猜你喜欢
      • 2011-10-02
      • 2013-06-09
      • 1970-01-01
      • 1970-01-01
      • 2021-08-27
      • 2015-10-18
      • 1970-01-01
      • 2018-05-27
      • 2012-04-24
      相关资源
      最近更新 更多