2015-06-09 8 views
1

У меня есть одна родительская таблица CUSTOMER_ACCOUNT и одна дочерняя таблица CUSTOMER_TEMPINFO.Unidirection OnetoOne сопоставление внешнего первичного ключа не генерируется в дочерней таблице

Я пытаюсь сгенерировать первичный ключ в родительской таблице и назначить его в дочерней таблице.

Я должен использовать однонаправленный способ, поэтому двунаправленное решение, пожалуйста, до абсолютно необходимого.

Есть что-то неправильное в заказе ассоциации!

Необходимо перейти от ребенка -> родитель?

Нужна подсказка и правильное объяснение!

Ниже перечислены сопоставления hbm.

CustomerAccount.hbm.xml

<hibernate-mapping> 
<class name="com.rup.example.po.CustomerAccount" table="CUSTOMER_ACCOUNT"> 
    <id name="customerId" type="int" column="customer_id"> 
     <generator class="native" /> 
    </id> 
    <property name="customerName" column="customer_name" type="string" /> 
    <property name="birthDay" column="birthday" type="date" /> 
    <one-to-one name="tempInfo" 
     class="com.rup.example.po.CustomerTempInfo" 
     property-ref="customerId" 
     cascade="all" /> 
</class> 
</hibernate-mapping> 

CustomerTempInfo.hbm.xml

<hibernate-mapping> 
<class name="com.rup.example.po.CustomerTempInfo" table="CUSTOMER_TEMPINFO"> 
    <id name="customerId" type="int" column="customer_id"> 
     <generator class="foreign"> 

     </generator> 
    </id> 
    <property name="passCode" column="pass_code" type="string" /> 
    <property name="codeExpiryDate" column="code_expiry_date" type="date" /> 
</class> 
</hibernate-mapping> 

И я получаю следующий след: -

Initial SessionFactory creation failed.org.hibernate.MappingException: Could not instantiate id generator [entity-name=com.rup.example.po.CustomerTempInfo] 
org.hibernate.MappingException: Could not instantiate id generator [entity-name=com.rup.example.po.CustomerTempInfo] 
    at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.createIdentifierGenerator(DefaultIdentifierGeneratorFactory.java:123) 
    at org.hibernate.mapping.SimpleValue.createIdentifierGenerator(SimpleValue.java:191) 
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:305) 
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1737) 
    at com.rup.example.util.HibernateUtil.buildSessionFactory(HibernateUtil.java:24) 
    at com.rup.example.util.HibernateUtil.getSessionFactory(HibernateUtil.java:36) 
    at com.rup.example.main.TestMainApp.main(TestMainApp.java:21) 
Caused by: org.hibernate.MappingException: param named "property" is required for foreign id generation strategy 
    at org.hibernate.id.ForeignGenerator.configure(ForeignGenerator.java:88) 
    at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.createIdentifierGenerator(DefaultIdentifierGeneratorFactory.java:117) 
    ... 6 more 
Exception in thread "main" java.lang.NullPointerException 
    at com.rup.example.main.TestMainApp.main(TestMainApp.java:40) 

ОБНОВЛЕНИЕ 20150610

Даже после рассмотрения двунаправленного пути, было возможно вставить запись, но не повезло, читая ту же спину. На этот раз получил следующий след -

Session created 
Hibernate: select hibernate_sequence.nextval from dual 
Hibernate: insert into CUSTOMER_TEMPINFO (pass_code, code_expiry_date, customer_id) values (?, ?, ?) 
Hibernate: insert into CUSTOMER_ACCOUNT (customer_name, birthday, customer_id) values (?, ?, ?) 
Customer ID=22 
Hibernate: select customerac0_.customer_id as customer_id1_0_0_, customerac0_.customer_name as customer_name2_0_0_, customerac0_.birthday as birthday3_0_0_ from CUSTOMER_ACCOUNT customerac0_ where customerac0_.customer_id=? 
Exception occured. null 
java.lang.NullPointerException 
    at org.hibernate.persister.entity.AbstractEntityPersister.loadByUniqueKey(AbstractEntityPersister.java:2385) 
    at org.hibernate.type.EntityType.loadByUniqueKey(EntityType.java:767) 
    at org.hibernate.type.EntityType.resolve(EntityType.java:505) 
    at org.hibernate.engine.internal.TwoPhaseLoad.doInitializeEntity(TwoPhaseLoad.java:170) 
    at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:144) 
    at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.performTwoPhaseLoad(AbstractRowReader.java:244) 
    at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishUp(AbstractRowReader.java:215) 
    at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:140) 
    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:138) 
    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:102) 
    at org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.load(AbstractLoadPlanBasedEntityLoader.java:186) 
    at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4126) 
    at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:503) 
    at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:468) 
    at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:213) 
    at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:146) 
    at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1070) 
    at org.hibernate.internal.SessionImpl.immediateLoad(SessionImpl.java:976) 
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:174) 
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:286) 
    at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185) 
    at com.rup.example.po.CustomerAccount_$$_jvst751_1.toString(CustomerAccount_$$_jvst751_1.java) 
    at java.lang.String.valueOf(String.java:2981) 
    at java.lang.StringBuilder.append(StringBuilder.java:131) 
    at com.rup.example.main.TestMainApp.printTransactionData(TestMainApp.java:65) 
    at com.rup.example.main.TestMainApp.main(TestMainApp.java:38) 
Closing SessionFactory 
Jun 10, 2015 11:55:19 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop 
INFO: HHH000030: Cleaning up connection pool [jdbc:oracle:thin:@localhost:1521:xe] 
+0

один хорошее руководство - http://stackoverflow.co м/вопросы/4756596/JPA-зимует-однонаправленный-один-к-одному-отображения-с-разделяемый первичным ключом?rq = 1 –

+0

Об обновлении 20150610. Операторы вставки выглядят странно. Экземпляр CustomerAccount является первым, который сохраняется, поскольку CustTempInfo получает свой основной ключ от родителя. Этот порядок вставки не будет работать, если у вас есть ограничение внешнего ключа на CustTempInfo на родительский ПК. Вы уверены, что данные, хранящиеся/зарегистрированные, верны? Я думаю, что Cascade All, определенный в родительской> дочерней ассоциации, может генерировать проблемы сперва persist (но не в фьючерсных обновлениях полученных объектов) – Guillermo

+0

Да. Записи были обновлены должным образом. Хотя его странно, что дочерний объект был сохранен первым, но во время отладки я мог видеть, что PK CustTempInfo заселен должным образом, хотя объект CustomerAccount не был сохранен до этого времени. –

ответ

0

К сожалению, необходимо указать, с которой связан объектом вы хотите, чтобы получить значение идентификатора, с помощью требуемого имущества property для инициализации иностранного генератора. Поэтому вам нужно добавить, по крайней мере, связь от дочернего к родительскому. Что-то вроде этого:

<hibernate-mapping> 
<class name="com.rup.example.po.CustomerTempInfo" table="CUSTOMER_TEMPINFO"> 
    <id name="customerId" type="int" column="customer_id"> 
     <generator class="foreign"> 
      <param name="property">parent</param> 
     </generator> 
    </id> 
    <property name="passCode" column="pass_code" type="string" /> 
    <property name="codeExpiryDate" column="code_expiry_date" type="date" /> 
    <one-to-one name="parent" class="com.rup.example.po.CustomerAccount" constrained="true" /> 
</class> 
</hibernate-mapping> 

Полезная ссылка: see 5.1.2.2.7. Identity copy (foreign generator)

+0

Мне не разрешено выставлять родителей в дочернем объекте. Хотя я пробовал этот подход и смог вставить запись. Но ударил еще один блокпост при чтении объекта. –

+0

Получил ошибку в спящем режиме https://hibernate.atlassian.net/browse/HHH-6813. Но я использую 4.3.6.Final, и это должно быть рассмотрено сейчас. –

0

Хорошо я получил его. Правило большого пальца с сопоставлением «один к одному», вы не можете позволить спящему режиму назначать PK дочернего объекта. Мне пришлось отдельно назначать PK у ребенка после выполнения saveOrUpdate.

Вот изменения, которые я сделал.

удалено свойство-исх

<one-to-one name="tempInfo" 
    class="com.rup.example.po.CustomerTempInfo" 
    cascade="all"/> 

назначен генератор

<class name="com.rup.example.po.CustomerTempInfo" table="CUSTOMER_TEMPINFO"> 
    <id name="customerId" type="int" column="customer_id"> 
     <generator class="assigned"/> 
    </id> 
    <property name="passCode" column="pass_code" type="string" /> 
    <property name="codeExpiryDate" column="code_expiry_date" type="timestamp" /> 
</class> 

и здесь идет основной метод: -

CustomerAccount account = new CustomerAccount(); 
account.setBirthDay(new Date()); 
account.setCustomerName("Rup Majumder"); 

tx = session.beginTransaction(); 
session.saveOrUpdate(account); 
CustomerTempInfo tempInfo = new CustomerTempInfo(); 
tempInfo.setCodeExpiryDate(new Date()); 
tempInfo.setPassCode("ABCD"); 
tempInfo.setCustomerId(account.getCustomerId()); 
account.setTempInfo(tempInfo); 
tx.commit(); 

Работал с 4.0.1.Final