Kann nicht java.lang.Integer Feld id für org.hibernate.id.IdentifierGeneratorHelper

Brauche ich, um zu speichern Sie einige Daten in eine MySQL-Datenbank mit Jpa 2/Hibernate 3.5.1. Für legacy-Gründen die Tabelle möchte ich Daten speichern, die in einen zusammengesetzten Primärschlüssel. Der erste Teil der Primärschlüssel vom Typ INTEGER (auto-Inkrement-Wert), der zweite Teil ist vom Typ BIGINT (Long in Java-code zu manuell eingestellt werden, bleiben).

Habe ich umgesetzt (Beispiel-code unter dem stacktrace) die kombinierte Primärschlüssel über @IdClass-Annotation, die erste-key-Teil hat auch eine generation-Strategie gesetzt: @GeneratedValue(strategy = GenerationType.IDENTITÄT)

Beim Versuch zu bestehen, ein Objekt mit code wie diesem

...
TestData testData = new TestData("data");
testData.setIdPartTwo(2L);

entityManager.getTransaction().begin();
entityManager.persist(testData);
entityManager.getTransaction().commit();

folgende exception geworfen wird:

javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: could not set a field value by reflection setter of org.example.persistence.TestDataId.idPartOne
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1235)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1168)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1174)
at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:674)
at org.example.persistence.PersistenceTest.shouldPersistTestData(PersistenceTest.java:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.testng.internal.MethodHelper.invokeMethod(MethodHelper.java:640)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:627)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:799)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1103)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:137)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:121)
at org.testng.TestRunner.runWorkers(TestRunner.java:1098)
at org.testng.TestRunner.privateRun(TestRunner.java:727)
at org.testng.TestRunner.run(TestRunner.java:581)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:315)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:310)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:272)
at org.testng.SuiteRunner.run(SuiteRunner.java:221)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:40)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:83)
at org.testng.internal.thread.ThreadUtil$CountDownLatchedRunnable.run(ThreadUtil.java:151)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)


Caused by: org.hibernate.PropertyAccessException: could not set a field value by reflection setter of org.example.persistence.TestDataId.idPartOne
at org.hibernate.property.DirectPropertyAccessor$DirectSetter.set(DirectPropertyAccessor.java:151)
at org.hibernate.mapping.Component$ValueGenerationPlan.execute(Component.java:438)
at org.hibernate.id.CompositeNestedGeneratedValueGenerator.generate(CompositeNestedGeneratedValueGenerator.java:122)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:122)
at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:69)
at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:179)
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:135)
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:61)
at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:800)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:774)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:778)
at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:668)
... 24 more


Caused by: java.lang.IllegalArgumentException: Can not set java.lang.Integer field org.example.persistence.TestDataId.idPartOne to org.hibernate.id.IdentifierGeneratorHelper$2
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:63)
at java.lang.reflect.Field.set(Field.java:657)
at org.hibernate.property.DirectPropertyAccessor$DirectSetter.set(DirectPropertyAccessor.java:139)
... 35 more

Meine entity-Klasse sieht wie folgt aus:

@Entity
@IdClass(TestDataId.class)
public class TestData implements Serializable {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Integer idPartOne;
  @Id
  private Long idPartTwo;
  private String data;
  public TestData() {}
    // getters and setters
    // hashCode() and equals()
}

Den kombinierten Primärschlüssel:

public class TestDataId implements Serializable {

  private static final long serialVersionUID = 1L;
  private Integer idPartOne;
  private Long idPartTwo;
  public TestDataId() {}
    // getters and setters
    // hashCode() and equals()
}

Test-Tabelle mit der folgenden Anweisung erstellt:

CREATE TABLE `testdb`.`testdata` 
(`idPartOne` INTEGER NOT NULL AUTO_INCREMENT,
 `idPartTwo` BIGINT(20) NOT NULL DEFAULT 0,
 `data` VARCHAR(45),
 PRIMARY KEY(`idPartOne`, `idPartTwo`))
ENGINE = InnoDB;

Änderung der GenerationType TABELLE würde es schaffen, aber erzeugen würde idPartOne-Werte in Schritten von ~32.000. Leider, eine andere Anwendung verwendet die gleiche Datenbank-Tabelle ohne JPA/Hibernate und ist schön Inkrementieren das id-Teil in Schritten von 1.

Ist es erforderlich, dass die id-Generierung erfolgt in der gleichen Weise-egal, welche Anwendung speichert die Daten in dieser Tabelle (das ist die id Inkrementieren von 1). Was wäre die beste Lösung, um dies zu erreichen? Hinweis, ändern wir nicht die andere Anwendung!

Jede Hilfe wird wirklich geschätzt.

Thx,

Markus

  • Die 'idParOne' ist eine inkrementelle automatisch, warum Sie definieren den PK der Tabelle als PRIMARY KEY(idPartOne, idPartTwo)? Ist es möglich, dass ein Datensatz in diese Tabelle eingefügt, aber mit duplizierten 'idPartOne'?
InformationsquelleAutor user506600 | 2010-11-13
Schreibe einen Kommentar