0

Let's assume I have a project done with hexagonal architecture together with DDD where my domain objects doesn't depend on any JPA implementation. Example project structure looks like below:

com.example.domain:

class User {
    Integer id;
    String username;
    List < Comment > comments;
}

class Comment {
    Integer id;
    String title;
}

com.example.infrastructure:

@Table
class UserEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Integer id;
    String username;
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    List < CommentEntity > comments;
}


@Table
class CommentEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Integer id;
    String title;
    @ManyToOne
    @JoinColumn(name = "user_id")
    User user;
}

class SqlUserRepository implements UserRepository {

    UserCrudRepository springDataUserRepo;

    User save(User user) {
        UserEntity userEntity = UserMapper.map(user);
        UserEntity savedEntity = springDataUserRepo.save(user);
        User mappedUser = UserMapper.map(savedEntity);
        return mappedUser;
    }

    User findById(Integer userId) {
        UserEntity findByIdEntity = springDataUserRepo.findById(Integer userId);
        User mappedUser = UserMapper.map(findByIdEntity);
        return mappedUser;
    }

}

com.example.application:

interface UserRepository {

    User save(User user);
    User findById(Integer id);

}

Now i have these two problems:

1. Object creation

I can't create new User and add few comments and save both parent and child objects with only one save() call on parent object. Like sth like below doesn't work:

User user = new User(null,"username",null);
Comment c1 = new Comment(null,"title1", user);
Comment c2 = new Comment(null,"title2", user);
user.setComments(List.of(c1,c2);
userRepository.save(user);

it complains that: Object references an unsaved transient ...

2. Updating the object (like removing one item from the comments list

For example, sth like this doesn't work:

User user = userRepository.findById(1);
Comment comments = user.getComments();
List<Comment> commentsMinusOne = comments.remove(0);
user.setComments(commentsMinusOne);
userRepository.save(user) //this will not remove one of the comments from db.

So my question is how people deal with these two issues when they do DDD + hexagonal architecture in Spring projects?

a4dev92
  • 531
  • 6
  • 15
  • Basically there's nothing wrong how you do this. Since `User` is your aggregate, the propagation of saving and deleting the `Comment`s can be "delegated" to JPA/Hibernate. I guess there's some issue in the mapping of the domain model `User` to the JPA entity `User`. Did you create new instances of the JPA entity of its `Comment`s? – Stefan Billmaier Mar 31 '23 at 14:21

0 Answers0