Persisting ManyToOne/OneToOne relations in Axon aggregate

Cascade types don’t seem to work with the entity manager that axon uses. If I use CascadeType.Persist, the second time I try to create an object with the same child I get a duplicate key constraint error. If I use CascadeType.Merge, it won’t work if the entries do not exist in the database.

Tried using different CascadeTypes, also the hibernate @Cascade annotations but with no avail. Also tried to use @AggregateMember for the children but the children entities don’t seem to be saved before the parent.

@Aggregate
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = {"id"}, callSuper = false)
@Builder
public class OfficialRecordEntity {
    @Id
    @AggregateIdentifier
    private String id;

    //many other fields

    @OneToMany(cascade = CascadeType.PERSIST)
    private List<Accessory> accessories;

    @ManyToOne(cascade = CascadeType.PERSIST)
    private ExpeditionType expeditionType;

    //many other commandhandlers/eventhandlers

    @CommandHandler
    public OfficialRecordEntity(CreateOfficialRecordCommand command) {
        apply(new CreateOfficialRecordEvent(command.getId(), command.getOfficialRecordDTO()));
    }

    @EventSourcingHandler
    public void on(final CreateOfficialRecordEvent event) {
        //...some field initializations    
    }
}

`

`

Asked this question a few days ago on stackoverflow here. Steven was kind enough to give me some tips but I didn’t manage to make much progress. I greated a github repo with what I’ve been trying out with his tips. The issue I have been having now with this solution is “Command ‘com.example.axon.domain.commands.CreateCourseCommand’ resulted in javax.persistence.PersistenceException(org.hibernate.PersistentObjectException: detached entity passed to persist: com.example.axon.model.Student)”. It seems that if the object already exists, it doesn’t attempt to override it, it just complains that it is detached…

So if anyone would be kind enough to give it a look and lead me on the right path I would really appreciate it!

Hi Vlad,

I believe I’ve tried to resolve your problem on Stack Overflow as well!
For reference to other readers, that post can be found here.

What my reply essentially comes down to, is showing a suggested approach we at AxonIQ use during the training.
The example exists out of a parent Aggregate Root with a list of Aggregate Entities under it, which works as expected using the State-Stored approach of an Aggregate.

As the training code isn’t publicly available, I made a small sample project on my own Github showing how this could work, which can be found here.
For quick reference, the ParentAggregate in the sample has a list of ChildEntity objects, which is set up as such:

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = “parentId”)
@AggregateMember
private List childEntities = new ArrayList<>();

Let us know if this resolve the problem at hand Vlad!

Cheers,
Steven