Home » Modeling » EMF » [CDO] Problems with unset EChar and PostgreSql backend
[CDO] Problems with unset EChar and PostgreSql backend [message #687604] |
Wed, 22 June 2011 20:18 |
Sed Mising name Messages: 22 Registered: July 2009 |
Junior Member |
|
|
I am having an issue right now with storing EChar values using CDO with a PostgreSql back end. The details seem to be related to the following factors:
1. Generated an ECore model with an object consisting of an EChar attribute.
2. If this value does not change and the object that holds this value is persisted through CDO, the DB returns the following exception:
org.eclipse.net4j.db.DBException: org.postgresql.util.PSQLException: ERROR: invalid byte sequence for encoding "UTF8": 0x00
Hint: This error can also happen if the byte sequence does not match the encoding expected by the server, which is controlled by "client_encoding".
at org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalAuditClassMapping.writeValues(HorizontalAuditClassMapping.java:465)
at org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.AbstractHorizontalClassMapping.writeRevision(AbstractHorizontalClassMapping.java:463)
at org.eclipse.emf.cdo.server.internal.db.DBStoreAccessor.writeRevision(DBStoreAccessor.java:401)
at org.eclipse.emf.cdo.server.internal.db.DBStoreAccessor.writeRevisions(DBStoreAccessor.java:382)
at org.eclipse.emf.cdo.spi.server.StoreAccessor.write(StoreAccessor.java:180)
at org.eclipse.emf.cdo.internal.server.TransactionCommitContext.write(TransactionCommitContext.java:328)
at org.eclipse.emf.cdo.spi.server.InternalCommitContext$1.runLoop(InternalCommitContext.java:35)
at org.eclipse.emf.cdo.spi.server.InternalCommitContext$1.runLoop(InternalCommitContext.java:1)
at org.eclipse.net4j.util.om.monitor.ProgressDistributor.run(ProgressDistributor.java:96)
at org.eclipse.emf.cdo.server.internal.net4j.protocol.CommitTransactionIndication.indicatingCommit(CommitTransactionIndication.java:316)
at org.eclipse.emf.cdo.server.internal.net4j.protocol.CommitTransactionIndication.indicating(CommitTransactionIndication.java:168)
at org.eclipse.emf.cdo.server.internal.net4j.protocol.CommitTransactionIndication.indicating(CommitTransactionIndication.java:122)
at org.eclipse.net4j.signal.IndicationWithMonitoring.indicating(IndicationWithMonitoring.java:84)
at org.eclipse.net4j.signal.IndicationWithResponse.doExtendedInput(IndicationWithResponse.java:90)
at org.eclipse.net4j.signal.Signal.doInput(Signal.java:315)
at org.eclipse.net4j.signal.IndicationWithResponse.execute(IndicationWithResponse.java:63)
at org.eclipse.net4j.signal.IndicationWithMonitoring.execute(IndicationWithMonitoring.java:63)
at org.eclipse.net4j.signal.Signal.runSync(Signal.java:240)
at org.eclipse.net4j.signal.Signal.run(Signal.java:146)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: org.postgresql.util.PSQLException: ERROR: invalid byte sequence for encoding "UTF8": 0x00
Hint: This error can also happen if the byte sequence does not match the encoding expected by the server, which is controlled by "client_encoding".
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2062)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1795)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:479)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:367)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:321)
at org.eclipse.emf.cdo.server.db.CDODBUtil.sqlUpdate(CDODBUtil.java:185)
at org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalAuditClassMapping.writeValues(HorizontalAuditClassMapping.java:461)
... 21 more
Last time I debugged, I believe that CDO is placing a null value in the parameters map of the PreparedStatement, but the error still seems to occur.
Based on the following threads:
http://archives.postgresql.org/pgsql-jdbc/2007-02/msg00102.php
and
http://stackoverflow.com/questions/1347646/postgres-error-on-insert-error-invalid-byte-sequence-for-encoding-utf8-0x00
I do realize this is server-specific behavior, and not directly attributed to CDO.
Unfortunately, I can't think of a workaround other than to change my model in such a way that what was the EChar/char attribute is translated to some kind of custom wrapper type that can be set to null.
It seems to me, and admittedly this may be naive, that because the model adheres to standard EMF generation, that CDO would be able handle persisting and retrieving an unset EChar attribute (again this may be too optimistic). I can definitely concede that since CDO does not proclaim direct support for PostgreSQL, I may be on my own here.
Does anyone have any ideas on how I can solve this problem without having to modify my model to get around this issue? And if I do have to modify the model, does the wrapping technique seem the most appropriate?
[Updated on: Thu, 23 June 2011 04:03] Report message to a moderator
|
|
|
Re: [CDO] Problems with unset EChar and PostgreSql backend [message #687787 is a reply to message #687604] |
Thu, 23 June 2011 08:30 |
Stefan Winkler Messages: 307 Registered: July 2009 Location: Germany |
Senior Member |
|
|
Hi Sed,
comments below.
Am 22.06.11 22:18, schrieb Sed:
> I am having an issue right now with storing EChar values using CDO with
> a PostgreSql back end. The details seem to be related to the following
> factors:
> 1. Generated an ECore model with an object consisting of an EChar
> attribute.
> 2. If this value does not change and the object that holds this value is
> persisted through CDO, the DB returns the following exception:
> org.eclipse.net4j.db.DBException: org.postgresql.util.PSQLException:
> ERROR: invalid byte sequence for encoding "UTF8": 0x00
> Hint: This error can also happen if the byte sequence does not match the
> encoding expected by the server, which is controlled by "client_encoding".
> at
> org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalAuditClassMapping.writeValues(HorizontalAuditClassMapping.java:465)
>
> at
> org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.AbstractHorizontalClassMapping.writeRevision(AbstractHorizontalClassMapping.java:463)
>
> at
> org.eclipse.emf.cdo.server.internal.db.DBStoreAccessor.writeRevision(DBStoreAccessor.java:401)
>
> at
> org.eclipse.emf.cdo.server.internal.db.DBStoreAccessor.writeRevisions(DBStoreAccessor.java:382)
>
> at
> org.eclipse.emf.cdo.spi.server.StoreAccessor.write(StoreAccessor.java:180)
> at
> org.eclipse.emf.cdo.internal.server.TransactionCommitContext.write(TransactionCommitContext.java:328)
>
> at
> org.eclipse.emf.cdo.spi.server.InternalCommitContext$1.runLoop(InternalCommitContext.java:35)
>
> at
> org.eclipse.emf.cdo.spi.server.InternalCommitContext$1.runLoop(InternalCommitContext.java:1)
>
> at
> org.eclipse.net4j.util.om.monitor.ProgressDistributor.run(ProgressDistributor.java:96)
>
> at
> org.eclipse.emf.cdo.server.internal.net4j.protocol.CommitTransactionIndication.indicatingCommit(CommitTransactionIndication.java:316)
>
> at
> org.eclipse.emf.cdo.server.internal.net4j.protocol.CommitTransactionIndication.indicating(CommitTransactionIndication.java:168)
>
> at
> org.eclipse.emf.cdo.server.internal.net4j.protocol.CommitTransactionIndication.indicating(CommitTransactionIndication.java:122)
>
> at
> org.eclipse.net4j.signal.IndicationWithMonitoring.indicating(IndicationWithMonitoring.java:84)
>
> at
> org.eclipse.net4j.signal.IndicationWithResponse.doExtendedInput(IndicationWithResponse.java:90)
>
> at org.eclipse.net4j.signal.Signal.doInput(Signal.java:315)
> at
> org.eclipse.net4j.signal.IndicationWithResponse.execute(IndicationWithResponse.java:63)
>
> at
> org.eclipse.net4j.signal.IndicationWithMonitoring.execute(IndicationWithMonitoring.java:63)
>
> at org.eclipse.net4j.signal.Signal.runSync(Signal.java:240)
> at org.eclipse.net4j.signal.Signal.run(Signal.java:146)
> at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
> at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
> at java.lang.Thread.run(Unknown Source)
> Caused by: org.postgresql.util.PSQLException: ERROR: invalid byte
> sequence for encoding "UTF8": 0x00
> Hint: This error can also happen if the byte sequence does not match the
> encoding expected by the server, which is controlled by "client_encoding".
> at
> org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2062)
>
> at
> org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1795)
>
> at
> org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
>
> at
> org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:479)
>
> at
> org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:367)
>
> at
> org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:321)
>
> at org.eclipse.emf.cdo.server.db.CDODBUtil.sqlUpdate(CDODBUtil.java:185)
> at
> org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.HorizontalAuditClassMapping.writeValues(HorizontalAuditClassMapping.java:461)
>
> ... 21 more
>
>
> Last time I debugged, I believe that CDO is placing a null value in the
> parameters map of the PreparedStatement, but the error still seems to
> occur.
>
> Based on the following threads:
> http://archives.postgresql.org/pgsql-jdbc/2007-02/msg00102.php
> and
> http://stackoverflow.com/questions/1347646/postgres-error-on-insert-error-invalid-byte-sequence-for-encoding-utf8-0x00
>
> I realize this is server-specific behavior, and not directly attributed
> to CDO.
>
> Unfortunately, I can't think of a workaround other than to change my
> model in such a way that what was the EChar/char attribute is translated
> to some kind of custom wrapper type that can be set to null.
> It seems to me, and admittedly this may be naive, that because the model
> adheres to standard EMF generation, that CDO would be able handle
> persisting and retrieving an unset EChar attribute (again this may be
> too optimistic).
You are right, basically. CDO should care about this. Sadly I didn't
have much time in the past to explicitly test the PostgreSQL DBStore.
There are some known issues (see Bugzilla).
To be clear what you mean: is the EChar EAttribute unsettable? Does it
have a default value?
I've had a quick look. I think, the problem here is that the character
data type is mapped to a string DB-type which does not allow for a zero
byte value. Could you check, if the code calls prepStmt.setString(i,
"\0x00") or if it calls prepStmt.setNull(i).
After checking this, can you please file a bug (maybe even with a test
case attached) so I can have a look and maybe fix it?
> Does anyone have any ideas on how I can solve this problem without
> having to modify my model to get around this issue? And if I do have to
> modify the model, does the wrapping technique seem the most appropriate?
Mhhh ... if it's the zero byte which causes trouble, you could try to
denote an explicit EDefaultValue to your EAttribute, so the zero byte
goes away. But I don't know if this helps. And this is just a workaround.
Cheers,
Stefan
|
|
|
Re: [CDO] Problems with unset EChar and PostgreSql backend [message #687878 is a reply to message #687787] |
Thu, 23 June 2011 12:48 |
Sed Mising name Messages: 22 Registered: July 2009 |
Junior Member |
|
|
Thanks for the quick reply!
Quote:To be clear what you mean: is the EChar EAttribute unsettable? Does it
have a default value?
The EChar EAttribute is settable (not unsettable). However, it does not have a default value explicitly set in the Ecore Model.
Quote:I've had a quick look. I think, the problem here is that the character
data type is mapped to a string DB-type which does not allow for a zero
byte value. Could you check, if the code calls prepStmt.setString(i,
"\0x00") or if it calls prepStmt.setNull(i).
It is calling prepStmt.setString (here's the debug stack:)
Jdbc3PreparedStatement(AbstractJdbc2Statement).setString(int, String) line: 1261
TypeMapping$TMCharacter.doSetValue(PreparedStatement, int, Object) line: 558
TypeMapping$TMCharacter(TypeMapping).setValue(PreparedStatement, int, Object) line: 145
TypeMapping$TMCharacter(TypeMapping).setDefaultValue(PreparedStatement, int) line: 108
TypeMapping$TMCharacter(TypeMapping).setValue(PreparedStatement, int, Object) line: 140
TypeMapping$TMCharacter(TypeMapping).setValueFromRevision(PreparedStatement, int, InternalCDORevision) line: 103
HorizontalAuditClassMapping.writeValues(IDBStoreAccessor, InternalCDORevision) line: 458
HorizontalAuditClassMapping(AbstractHorizontalClassMapping).writeRevision(IDBStoreAccessor, InternalCDORevision, OMMonitor) line: 463
...
The class org.eclipse.emf.cdo.server.internal.db.mapping.TypeMapping calls getDefaultValue(), which ultimately sets the '\u0000' char as the default value at
org.eclipse.emf.ecore.impl.EDataTypeImpl#getDefaultValue() [appx line 112].
Quote:After checking this, can you please file a bug (maybe even with a test
case attached) so I can have a look and maybe fix it?
Sure thing, its now bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=350137
Quote:If it's the zero byte which causes trouble, you could try to
denote an explicit EDefaultValue to your EAttribute, so the zero byte
goes away. But I don't know if this helps. And this is just a workaround.
I'd love to be able to get away with this, but picking a default value (other than the '\u0000' it already has) would be very difficult since the purpose of that attribute is intended to represent any valid character (i.e. there is no smaller subset of 'valid' characters so that I could pick a 'unvalid' character as a default).
|
|
|
Goto Forum:
Current Time: Thu Apr 25 14:10:24 GMT 2024
Powered by FUDForum. Page generated in 1.07631 seconds
|