0

I am trying to use the PartyId ( a value object) as Id in spring data JDBC. I am setting the value in PartyId (you can see in first screen shot below), but at time of inserting it gives following error.

PartyId debug image

Debug Screen shot of cause

enter image description here

Stack Trace

Caused by: org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL 

[INSERT INTO "party" ("currency_uom_id", "description", "party_id", "party_type_id", "status_id", "version") VALUES (?, ?, ?, ?, ?, ?)]; ERROR: null value in column "party_id" violates not-null constraint
  Detail: Failing row contains (null, null, Organisation, USD, Enable, 1).; nested exception is org.postgresql.util.PSQLException: ERROR: null value in column "party_id" violates not-null constraint
  Detail: Failing row contains (null, null, Organisation, USD, Enable, 1).
    at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:251) ~[spring-jdbc-5.3.5.jar:5.3.5]
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:70) ~[spring-jdbc-5.3.5.jar:5.3.5]
    at org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1541) ~[spring-jdbc-5.3.5.jar:5.3.5]
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:667) ~[spring-jdbc-5.3.5.jar:5.3.5]
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:991) ~[spring-jdbc-5.3.5.jar:5.3.5]
    at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.update(NamedParameterJdbcTemplate.java:356) ~[spring-jdbc-5.3.5.jar:5.3.5]
    at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.update(NamedParameterJdbcTemplate.java:340) ~[spring-jdbc-5.3.5.jar:5.3.5]
    at org.springframework.data.jdbc.core.convert.DefaultDataAccessStrategy.insert(DefaultDataAccessStrategy.java:138) ~[spring-data-jdbc-2.1.6.jar:2.1.6]
    at org.springframework.data.jdbc.core.JdbcAggregateChangeExecutionContext.executeInsertRoot(JdbcAggregateChangeExecutionContext.java:90) ~[spring-data-jdbc-2.1.6.jar:2.1.6]
    at org.springframework.data.jdbc.core.AggregateChangeExecutor.execute(AggregateChangeExecutor.java:66) ~[spring-data-jdbc-2.1.6.jar:2.1.6]
    ... 96 common frames omitted

The error says , PartyId is null , which violets the db constraints.

Party Class as Aggregate Root

@AccessType(AccessType.Type.PROPERTY)
public class Party  implements AggregateRoot   {
    //Business key Id;
    @Id//Use by spring data jdbc
    @Embedded(onEmpty = USE_NULL)
    private PartyId partyId; // private String partyId - this is working (removing @Embedded also)
    private String description;
    @Embedded(onEmpty = USE_NULL)
    private PartyTypeId partyTypeId;
    @Embedded(onEmpty = USE_NULL)
    private CurrencyUomId currencyUomId;
    @Embedded(onEmpty = USE_NULL)
    private StatusId statusId;

    @Version
    private long version;
    /*private List<PartyAttributes> partyAttributes = new ArrayList<>();
    private List<PartyCarrierAccount>   partyCarrierAccounts = new ArrayList<>();*/

     //Only package level access
     public Party(PartyId partyId,String description,PartyTypeId partyTypeId,CurrencyUomId currencyUomId,StatusId statusId,List<PartyAttributes> partyAttributes,List<PartyCarrierAccount> partyCarrierAccounts){
         this.partyId = partyId;
         this.partyTypeId = partyTypeId;
         this.currencyUomId = currencyUomId;
         this.statusId = statusId;
         
    }

The insert will work if I make partyId as String (private String partyId in Party class, obviously removing @Embeded annotation from partyId)

Ashwani Tiwari
  • 1,497
  • 18
  • 28

2 Answers2

1

Spring Data JDBC does not yet supports embedded ids. But since your PartyId seems to contain only a single value, you can register a custom conversion for it and get the result you want.

Here is an example for registering conversions.

You create a configuration class like the following

@Configuration
static class ConversionConfigurationApplication extends AbstractJdbcConfiguration {

    @Override
    @Bean
    public JdbcCustomConversions jdbcCustomConversions() {
        return new JdbcCustomConversions(asList(PartyIdToString.INSTANCE, StringToPartyId.INSTANCE));
    }


    @WritingConverter
    enum PartyIdToString implements Converter<PartyId, String> {

        INSTANCE;

        @Override
        public String convert(PartyId source) {
            return source.partyId;
        }
    }

    @ReadingConverter
    enum StringToPartyId implements Converter<String, PartyId> {

        INSTANCE;

        @Override
        public PartyId convert(String source) {
            return new PartyId(source);
        }
    }

}
Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
  • I configured the converts , but getting this error org.springframework.data.mapping.MappingException: Couldn't find PersistentEntity for type class com.gerps.UserServices.domain.partybc.party.PartyId! at org.springframework.data.mapping.context.MappingContext.getRequiredPersistentEntity(MappingContext.java:79) ~[spring-data-commons-2.4.6.jar:2.4.6] at org.springframework.data.jdbc.core.convert.BasicJdbcConverter$ReadingContext.extendBy(BasicJdbcConverter.java:403) ~[spring-data-jdbc-2.1.6.jar:2.1.6] at org.springframework.data.jdbc.core.convert.BasicJdbcConverter$ReadingContext.read – Ashwani Tiwari Apr 01 '21 at 08:03
  • Can you upgrade to the latest version and try again? Although it should work with the version you are using. If it still doesn't work, please file an issue with a reproducer. – Jens Schauder Apr 01 '21 at 09:06
  • The relevant issue that introduced this is here: https://github.com/spring-projects/spring-data-jdbc/issues/571 – Jens Schauder Apr 01 '21 at 09:07
0
  1.   @EmbeddedId   //have not found onEmpty parameter in any documentation 
      private PartyId partyId;
    
  2.  @Embeddable
     public class PartyId
    
  3. Override equals and hashcode methods on Party class to consider the partyId field.

  4. go to PartyId class and override equals and hashcode methods to consider all id fields of class PartyId

Panagiotis Bougioukos
  • 15,955
  • 2
  • 30
  • 47