java idGenertor_无法将java.lang.Integer字段id设置为org.hibernate.id.IdentifierGeneratorHelper...

我需要使用Jpa 2 / Hibernate 3.5.1在MySQL数据库中存储一些数据。由于遗留原因,我想要存储数据的表具有复合主键。主键的第一部分是INTEGER类型(自动增量值),第二部分是BIGINT类型(Java代码中的长 - 在持久化之前手动设置)。

我已经通过@ IdClass-Annotation实现了(堆栈跟踪下面的示例代码)组合主键,第一个键部分也有一个生成策略集:@GeneratedValue(strategy = GenerationType.IDENTITY)

当试图用这样的代码持久化对象时

...

TestData testData = new TestData("data");

testData.setIdPartTwo(2L);

entityManager.getTransaction().begin();

entityManager.persist(testData);

entityManager.getTransaction().commit();

抛出以下异常:

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

我的实体类看起来像这样:

@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()

}

组合主键:

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()

}

使用以下语句创建了测试表:

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;

将GenerationType更改为TABLE将使其工作,但会以~32.000的步长生成idPartOne值。不幸的是,另一个应用程序在没有JPA / Hibernate的情况下使用这个非常相同的数据库表,并且以1为步长很好地增加了这个id-part。

无论哪个应用程序将数据存储到该表中(即,id递增为1),都需要以相同的方式完成id生成。实现这一目标的最佳解决方案是什么?提示,我们无法更改其他应用程序!

任何帮助都非常感谢。

谢谢,

马库斯

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值