Description
mikleing opened DATAJDBC-326 and commented
The ID linking two entities in a One to Many Relationship is not being properly converted. The other IDs in the code are being converted correctly. And the following code works if I switch my ID types from UUID back to Integer.
Setup
Below is the setup for this issue. Note that I'm using MySQL and the default driver. And I'm using the standard UUID class in Java (java.util.UUID).
Entities
public class Role extends Entity {
@Id
public UUID id;
}
public class UserRole {
public UUID role;
}
public class User {
@Id
public UUID id;
Set<UserRole> userRoles = new HashSet<>();
}
Converters
@WritingConverter
public static class UuidToByteConverter implements Converter<UUID, byte[]>{
@Override public byte[] convert(UUID source) {
ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[16]);
byteBuffer.putLong(source.getMostSignificantBits());
byteBuffer.putLong(source.getLeastSignificantBits());
return byteBuffer.array();
}
}
@ReadingConverter
public static class ByteToUuidConverter implements Converter<byte[], UUID> {
@Override public UUID convert(byte[] source) {
ByteBuffer byteBuffer = ByteBuffer.wrap(source);
Long high = byteBuffer.getLong();
Long low = byteBuffer.getLong();
return new UUID(high, low);
}
}
ID
A new UUID is created for a new entity when the BeforeSaveEvent.is triggered.
Issue
The following code to save a role works fine.
Role role = new Role();
role = roleRepository.save(role);
The following code to save the User fails.
UserRole userRole = new UserRole();
userRole.role = role.id;
User user = new User();
user.userRoles.add(userRole);
userRepository.save(user);
Here is the error message:
com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Data too long for column 'user' at row 1 at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:104) ~[mysql-connector-java-8.0.13.jar:8.0.13] at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:974) ~[mysql-connector-java-8.0.13.jar:8.0.13] at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1113) ~[mysql-connector-java-8.0.13.jar:8.0.13] at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1061) ~[mysql-connector-java-8.0.13.jar:8.0.13]
...
The following packet is what is being sent to the database.
03 49 4e 53 45 52 54 20 . I N S E R T
49 4e 54 4f 20 55 73 65 I N T O U s e
72 52 6f 6c 65 20 28 72 r R o l e ( r
6f 6c 65 2c 20 75 73 65 o l e , u s e
72 29 20 56 41 4c 55 45 r ) V A L U E
53 20 28 78 27 34 44 31 S ( x ' 4 D 1
30 30 39 36 33 34 37 39 0 0 9 6 3 4 7 9
46 34 32 41 45 42 33 30 F 4 2 A E B 3 0
37 33 41 31 37 33 37 31 7 3 A 1 7 3 7 1
37 30 41 45 43 27 2c 20 7 0 A E C ' ,
5f 62 69 6e 61 72 79 27 _ b i n a r y '
ac ed 5c 30 05 73 72 5c . . \ 0 . s r \
30 0e 6a 61 76 61 2e 75 0 . j a v a . u
74 69 6c 2e 55 55 49 44 t i l . U U I D
bc 99 03 f7 98 6d 85 2f . . . . . m . /
02 5c 30 02 4a 5c 30 0c . \ 0 . J \ 0 .
6c 65 61 73 74 53 69 67 l e a s t S i g
42 69 74 73 4a 5c 30 0b B i t s J \ 0 .
6d 6f 73 74 53 69 67 42 m o s t S i g B
69 74 73 78 70 9a e4 03 i t s x p . . .
72 c9 54 9f 1d e9 37 e5 r . T . . . 7 .
a4 45 96 4d 2b 27 29 . E . M + ' )
The role has been properly converted to a byte array. But the user appears to be something different. And that is the problem. The user should also be a byte array
Affects: 1.0.4 (Lovelace SR4)
Referenced from: pull request #118