Код, сгенерированный liferay 7: blob не записан в postgresql
Я следовал этому руководству, пытаясь реализовать хранение файлов в БД для портлета liferay (используя liferay-ce-portal-tomcat-7.0-ga5 с PostgreSQL 9.6). Service.xml:
<entity name="MyBlob" local-service="true" table="_MY_BLOB_IMP" human-name="My blobs">
<column name="myBlobId" type="long" primary="true"
id-type="increment">
</column>
<column name="data" type="Blob"></column>
</entity>
Portlet.java:
long blobId = CounterLocalServiceUtil.increment(MyBlob.class.getName());
MyBlob blob = _myBlobLocalService.createMyBlob(blobid);
blob.setData(blobData);
//_myBlobLocalService.addMyBlob(blob);
MyBlobLocalServiceUtil.addMyBlob(blob);
Я получил ошибку:
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:85)
at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:70)
at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:90)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:268)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:185)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at com.liferay.portal.dao.orm.hibernate.event.NestableFlushEventListener.onFlush(NestableFlushEventListener.java:61)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
at com.liferay.portal.dao.orm.hibernate.SessionImpl.flush(SessionImpl.java:173)
at com.liferay.portal.kernel.dao.orm.ClassLoaderSession.flush(ClassLoaderSession.java:282)
в коде, сгенерированном сервис-сборщиком в строке "session.flush();":
try {
session = openSession();
if (myBlob.isNew()) {
session.save(myBlob);
myBlob.setNew(false);
}
else {
session.evict(myBlob);
session.saveOrUpdate(myBlob);
}
session.flush();
session.clear();
}
Вот журнал postgres:
2017-11-27 14:55:35 CET [20752]: [4131-1] user=liferay_umsw,db=umswportal,app=PostgreSQL JDBC Driver,client=127.0.0.1 LOG: execute S_6: select resourcepe0_.resourcePermissionId as resource1_269_, resourcepe0_.mvccVersion as mvccVers2_269_, resourcepe0_.companyId as companyId269_, resourcepe0_.name as name269_, resourcepe0_.scope as scope269_, resourcepe0_.primKey as primKey269_, resourcepe0_.primKeyId as primKeyId269_, resourcepe0_.roleId as roleId269_, resourcepe0_.ownerId as ownerId269_, resourcepe0_.actionIds as actionIds269_, resourcepe0_.viewActionId as viewAct11_269_ from ResourcePermission resourcepe0_ where (resourcepe0_.companyId=$1 )AND(resourcepe0_.name=$2 )AND(resourcepe0_.scope=$3 )AND(resourcepe0_.primKey=$4 )AND(resourcepe0_.roleId=$5 )
2017-11-27 14:55:35 CET [20752]: [4132-1] user=liferay_umsw,db=umswportal,app=PostgreSQL JDBC Driver,client=127.0.0.1 DETAIL: parameters: $1 = '20116', $2 = 'Zalacznik', $3 = '1', $4 = '20116', $5 = '20123'
2017-11-27 14:55:35 CET [20752]: [4133-1] user=liferay_umsw,db=umswportal,app=PostgreSQL JDBC Driver,client=127.0.0.1 LOG: execute S_6: select resourcepe0_.resourcePermissionId as resource1_269_, resourcepe0_.mvccVersion as mvccVers2_269_, resourcepe0_.companyId as companyId269_, resourcepe0_.name as name269_, resourcepe0_.scope as scope269_, resourcepe0_.primKey as primKey269_, resourcepe0_.primKeyId as primKeyId269_, resourcepe0_.roleId as roleId269_, resourcepe0_.ownerId as ownerId269_, resourcepe0_.actionIds as actionIds269_, resourcepe0_.viewActionId as viewAct11_269_ from ResourcePermission resourcepe0_ where (resourcepe0_.companyId=$1 )AND(resourcepe0_.name=$2 )AND(resourcepe0_.scope=$3 )AND(resourcepe0_.primKey=$4 )AND(resourcepe0_.roleId=$5 )
2017-11-27 14:55:35 CET [20752]: [4134-1] user=liferay_umsw,db=umswportal,app=PostgreSQL JDBC Driver,client=127.0.0.1 DETAIL: parameters: $1 = '20116', $2 = 'Zalacznik', $3 = '2', $4 = '20143', $5 = '20123'
2017-11-27 14:55:35 CET [20752]: [4135-1] user=liferay_umsw,db=umswportal,app=PostgreSQL JDBC Driver,client=127.0.0.1 LOG: execute S_6: select resourcepe0_.resourcePermissionId as resource1_269_, resourcepe0_.mvccVersion as mvccVers2_269_, resourcepe0_.companyId as companyId269_, resourcepe0_.name as name269_, resourcepe0_.scope as scope269_, resourcepe0_.primKey as primKey269_, resourcepe0_.primKeyId as primKeyId269_, resourcepe0_.roleId as roleId269_, resourcepe0_.ownerId as ownerId269_, resourcepe0_.actionIds as actionIds269_, resourcepe0_.viewActionId as viewAct11_269_ from ResourcePermission resourcepe0_ where (resourcepe0_.companyId=$1 )AND(resourcepe0_.name=$2 )AND(resourcepe0_.scope=$3 )AND(resourcepe0_.primKey=$4 )AND(resourcepe0_.roleId=$5 )
2017-11-27 14:55:35 CET [20752]: [4136-1] user=liferay_umsw,db=umswportal,app=PostgreSQL JDBC Driver,client=127.0.0.1 DETAIL: parameters: $1 = '20116', $2 = 'Zalacznik', $3 = '4', $4 = 'Zalacznik', $5 = '20123'
2017-11-27 14:55:35 CET [20752]: [4137-1] user=liferay_umsw,db=umswportal,app=PostgreSQL JDBC Driver,client=127.0.0.1 LOG: execute S_10: BEGIN
2017-11-27 14:55:35 CET [20752]: [4138-1] user=liferay_umsw,db=umswportal,app=PostgreSQL JDBC Driver,client=127.0.0.1 LOG: execute <unnamed>: insert into _ZALACZNIK_BLOB_IMP (zalacznikBlobId) values ($1)
2017-11-27 14:55:35 CET [20752]: [4139-1] user=liferay_umsw,db=umswportal,app=PostgreSQL JDBC Driver,client=127.0.0.1 DETAIL: parameters: $1 = '4'
2017-11-27 14:55:35 CET [20752]: [4140-1] user=liferay_umsw,db=umswportal,app=PostgreSQL JDBC Driver,client=127.0.0.1 LOG: fastpath function call: "lo_creat" (OID 957)
2017-11-27 14:55:35 CET [20752]: [4141-1] user=liferay_umsw,db=umswportal,app=PostgreSQL JDBC Driver,client=127.0.0.1 LOG: fastpath function call: "lo_open" (OID 952)
2017-11-27 14:55:35 CET [20752]: [4142-1] user=liferay_umsw,db=umswportal,app=PostgreSQL JDBC Driver,client=127.0.0.1 LOG: fastpath function call: "lowrite" (OID 955)
2017-11-27 14:55:35 CET [20752]: [4143-1] user=liferay_umsw,db=umswportal,app=PostgreSQL JDBC Driver,client=127.0.0.1 LOG: fastpath function call: "lowrite" (OID 955)
2017-11-27 14:55:35 CET [20752]: [4144-1] user=liferay_umsw,db=umswportal,app=PostgreSQL JDBC Driver,client=127.0.0.1 LOG: fastpath function call: "lowrite" (OID 955)
( . . . )
2017-11-27 14:55:35 CET [20752]: [4179-1] user=liferay_umsw,db=umswportal,app=PostgreSQL JDBC Driver,client=127.0.0.1 LOG: fastpath function call: "lowrite" (OID 955)
2017-11-27 14:55:35 CET [20752]: [4180-1] user=liferay_umsw,db=umswportal,app=PostgreSQL JDBC Driver,client=127.0.0.1 LOG: fastpath function call: "lo_close" (OID 953)
2017-11-27 14:55:35 CET [20752]: [4181-1] user=liferay_umsw,db=umswportal,app=PostgreSQL JDBC Driver,client=127.0.0.1 LOG: execute <unnamed>: update _MY_BLOB_IMP set data=$1 where myBlobId=$2
2017-11-27 14:55:35 CET [20752]: [4182-1] user=liferay_umsw,db=umswportal,app=PostgreSQL JDBC Driver,client=127.0.0.1 DETAIL: parameters: $1 = '23373', $2 = '204'
2017-11-27 14:55:35 CET [20752]: [4183-1] user=liferay_umsw,db=umswportal,app=PostgreSQL JDBC Driver,client=127.0.0.1 LOG: execute S_33: ROLLBACK
Является ли код из примера недействительным для liferay 7, должен ли я реализовывать BLOB-объекты для Postgre каким-либо другим способом или я совершаю другую ошибку?
Спасибо,
ОБНОВЛЕНИЕ: удаление session.flush () и session.clear() не помогает, он перемещает ошибку для фиксации...
at com.liferay.portal.spring.hibernate.PortletTransactionManager$TransactionStatusWrapper.reset(PortletTransactionManager.java:260)
at com.liferay.portal.spring.hibernate.PortletTransactionManager.commit(PortletTransactionManager.java:63)
at com.liferay.portal.spring.transaction.DefaultTransactionExecutor._commit(DefaultTransactionExecutor.java:128)
at com.liferay.portal.spring.transaction.DefaultTransactionExecutor.commit(DefaultTransactionExecutor.java:36)
at com.liferay.portal.spring.transaction.DefaultTransactionExecutor.execute(DefaultTransactionExecutor.java:62)
at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:58)
at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:137)
2 ответа
Это похоже на проблему с вашим автоинкрементом.
Вы можете сделать 2 вещи
1) Проверьте, настроена ли ваша таблица базы данных (_MY_BLOB_IMP) для автоинкремента.
2) Измените ваш service.xml и удалите id-type="increment" и обновите сервисы.
и обнови свой код..
long blobId = CounterLocalServiceUtil.increment(MyBlob.class.getName()); MyBlob blob = _myBlobLocalService.createMyBlob(blobid); blob.setData(blobData); //_myBlobLocalService.addMyBlob(blob); MyBlobLocalServiceUtil.addMyBlob(blob);
Вы начинаете транзакцию раньше (я вижу это в логах)
insert into _ZALACZNIK_BLOB_IMP (zalacznikBlobId) values ($1)
но позже вы сбрасываете и закрываете сессию без фиксации - поэтому ваши изменения не сохраняются в БД, попробуйте добавить коммит до session.close()
например, если у вас есть
Transaction tx = sess.beginTransaction();
добавлять
tx.commit();