2010-11-13 17 views
5

Bazı verileri bir MySQL veritabanında Jpa 2/Hibernate 3.5.1 kullanarak kaydetmem gerekiyor. Eski nedenlerden dolayı verileri depolamak istediğim tablonun birleşik birincil anahtarı var. Birincil anahtarın ilk kısmı INTEGER (otomatik artış-değer) tipindedir, ikinci kısım BIGINT (Java-kodunda uzun - devam etmeden önce manuel olarak ayarlanmalıdır) tipindedir. @GeneratedValue (strateji = GenerationType.IDENTITY)java.lang.Integer alan kimliği ayarlanamaz org.hibernate.id.IdentifierGeneratorHelper

:

I (stacktrace aşağıdaki örnek kodu) @ IdClass-Açıklaması ile kombine birincil anahtar uygulayan birinci anahtar bölümü de bir kuşak stratejisi seti vardır Bu

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

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

gibi koduyla bir nesne devam çalışırken

şu istisnası atılır:

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 

Benim varlık sınıfı l görünüyor ike bu:

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

kombine birincil anahtar:

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; 

o iş yapacak TABLO GenerationType değiştirme:

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-Masa aşağıdaki deyimi ile oluşturuldu Ancak, ~ 32.000'lik adımlarla idPartOne değerleri üretecektir. Ne yazık ki, başka bir uygulama, JPA/Hazırda Bekletme olmadan bu aynı veritabanı tablosunu kullanır ve bu adımı 1 adımda güzelce arttırır.

Kimlik kipi, hangi uygulama olursa olsun aynı şekilde yapılır. verileri bu tabloya kaydeder (yani, 1'in artırılması id). Bunu başarmak için en iyi çözüm ne olurdu? İpucu, diğer uygulamayı değiştiremeyiz!

Herhangi bir yardım gerçekten takdir edilmektedir. Eğer gömülü id açıklama yaparken

Thx,

+0

'idParOne', otomatik olarak artan nedir? Bu tablonun içine bir kayıt eklenmiş, ancak 'idPartOne' yinelenen ile mümkün mü? –

cevap

1

Markus İşe yarıyor mu? Eğer PRIMARY KEY (`idPartOne`,` idPartTwo`) olarak tablonun PK tanımlamak neden

@Embeddable 
public class TestDataId 
{ 
    @GeneratedValue(strategy = GenerationType.TABLE) 
    private Integer idPartOne; 
    private Long idPartTwo; 
} 

@Entity 
public class TestData 
{ 
    @EmbeddedId 
    private TestDataId key; 
    private String data; 
} 
İlgili konular