Search code examples
postgresqljdbcmicronautcomposite-primary-keymicronaut-data

Error column specified more than once when inserting an entity with EmbeddedId using Micronaut Data


I'm using Micronaut Data JDBC and I'm facing an error. I have this entity:

@MappedEntity(value = "document_metadata")
@AllArgsConstructor
@EqualsAndHashCode
public class DocumentMetadataJDBCEntity implements DocumentMetadata {

    @Embeddable
    @AllArgsConstructor
    public static class MetadataPk {

        @MappedProperty(value = "document_uid")
        @NotNull
        private UUID documentUid;

        @MappedProperty(value = "metadata_key")
        @NotNull
        private String metadataKey;

        public UUID getDocumentUid() {
            return documentUid;
        }

        public String getMetadataKey() {
            return metadataKey;
        }

    }

    @EmbeddedId
    private MetadataPk metadataPk;

    @NotNull
    private String metadataValue;

    public MetadataPk getMetadataPk() {
        return metadataPk;
    }

    @Override
    public String getMetadataKey() {
        return getMetadataPk().getMetadataKey();
    }

    @Override
    public String getMetadataValue() {
        return metadataValue;
    }

    public UUID getDocumentUid() {
        return getMetadataPk().getDocumentUid();
    }

}

And when inserting I get this error:

io.micronaut.data.exceptions.DataAccessException: SQL error executing INSERT: Batch entry 0 INSERT INTO "document_metadata" ("metadata_key","metadata_value","document_uid","document_uid","metadata_key") VALUES ('id','1234','c960d8de-99a4-40a6-91bf-b0d4a73910d6'::uuid,'c960d8de-99a4-40a6-91bf-b0d4a73910d6'::uuid,'id') was aborted: ERROR: column "document_uid" specified more than once

The code for saving is the next one:

Set<DocumentMetadataJDBCEntity> metadataSet = metadata.entrySet().stream()
                .map(e -> new DocumentMetadataJDBCEntity(new DocumentMetadataJDBCEntity.MetadataPk(
                        savedDocument.getUid(), e.getKey()), e.getValue())).collect(toSet());
        Iterable<DocumentMetadataJDBCEntity> persistedMetadata = documentMetadataJDBCRepository.saveAll(metadataSet);

Any idea?


Solution

  • Add @Transient to your convenience accessor (getter) methods:

        @Override
        @Transient
        public String getMetadataKey() {
            return getMetadataPk().getMetadataKey();
        }
    
        @Transient
        public UUID getDocumentUid() {
            return getMetadataPk().getDocumentUid();
        }
    

    It "tells" Micronaut not to save the return value into the DB.