Designing DAOs that handle composite objects Suppose I have following elementary DTOs, each DTO corresponding to a database table:

class Event {
    String name
}
class Player {
    String name
}


DAOs for elementary DTOs:

class PlayerDao {
    def insert(Player p) {
        //sql to insert local members
    }
}
class EventDao {
    def insert(Event e) {
        //sql to insert local members
    }
}


Composite DTO related to other DTOs via foreign keys:

class Game {
    Event e
    Player p
    Date d
}


Now there are two approaches to designing the DAO for game object:

Have the caller hand over entire game object to GameDao and GameDao calls other DAOs to save the child objects.

class GameDao {
    def insert(Game g) {
        eventDao.insert(g.e)
        playerDao.insert(g.p)
        //sql to insert local members
    }   
}
class Caller {
    def static main(String[] a) {
        def g = new Game()
        gameDao.insert(g)
    }
}


Make GameDao save only local state of object and leave the responsibility of saving related objects to caller.

class GameDao {
    def insert(Game g) {
        //sql to insert local members
    }   
}
class Caller {
    def static main(String[] a) {
        def g = new Game()
        eventDao.insert(g.e)
        playerDao.insert(g.p)
        gameDao.insert(g)
    }
}


Use of an ORM is out of question.

Which design is better and why?
I would go for the first one, because it exposes a much simpler API to the caller.

The day you need to add anything to your design, if it's encapsulated this way, the caller doesn't need to change a thing and it's still going to work, because the Game knows how to build itself and doesn't put that burden onto the caller.