Проблемы Hiberate, для jdbc IDENTITY_INSERT установлено значение OFF - PullRequest
9 голосов
/ 17 января 2009

Я получаю сообщение об ошибке JDBC при попытке выполнить коммит через спящий режим на SQL Server

Невозможно вставить явное значение для столбца идентификаторов в таблице «Отчет», если для параметра 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>

Что мне кажется, что он должен делать идентификационную вставку правильно.

Есть идеи, как это исправить?

EDIT:
Некоторые ссылки на документацию, для потомков,
http://www.hibernate.org/hib_docs/v3/reference/en-US/html/mapping.html#mapping-declaration-id-generator
http://www.roseindia.net/hibernate/hibernateidgeneratorelement.shtml

Ответы [ 5 ]

8 голосов
/ 17 января 2009

Нельзя вставить в столбец идентификаторов в SQL Server, если для параметра "IDENTITY_INSERT" не установлено значение "ON". Поскольку ваш класс генератора «назначен», Hibernate предполагает, что вы устанавливаете явное значение «id» в Java перед сохранением объекта, и что Hibernate может напрямую вставить значение в базу данных. Вам нужно либо:

  1. Выберите другой класс генератора, например "родной"
  2. Установите для IDENTITY_INSERT значение "ON"
1 голос
/ 02 октября 2013

попробуйте изменить тип класса генератора с «назначенного» на «идентификатор», у меня это сработало

1 голос
/ 10 апреля 2013

Изменить тип генератора класса

до

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

ПОСЛЕ

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

Теперь это будет работать!

1 голос
/ 04 апреля 2013

Вот кое-что, что сработало для меня. Адаптируйте по необходимости.

@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 имела то же имя, что и класс Entity. Для вас это, вероятно, не соответствует действительности. Тогда одним из решений будет запрос имени таблицы в качестве параметра.

1 голос
/ 13 июля 2012

Лучше использовать классы-обертки, такие как 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...