Beispiel #1
0
  public Team insertWithTxHandle(final Team team) {
    // in this case we use an explicit handle, and attach the dao's to the same handle (connection)
    try (Handle handle = jdbiHelper.getTxHandle()) {
      handle.begin();
      TeamDao teamDao = handle.attach(TeamDao.class);
      TeamPersonDao teamPersonDao =
          handle.attach(TeamPersonDao.class); // team->person mapping table

      long teamId;
      if (team.getPointOfContact() != null) {
        teamId = teamDao.insertWithPoC(team);
      } else {
        teamId = teamDao.insertWithoutPoC(team);
      }
      for (Person p : team.getMembers()) {
        // update the team->person mapping table
        teamPersonDao.insert(new TeamPerson(teamId, p.getId()));
      }
      // add test code for checking that TX is handled correctly
      checkIfTxShouldBeRolledBack(team);
      handle.commit();
      return get(teamId);
    }
  }
Beispiel #2
0
/**
 * Repository for {@link no.kodemaker.ps.jdbiapp.domain.Team} objects. The {@link
 * no.kodemaker.ps.jdbiapp.domain.Person} collection association is mapped via a mapping table
 * (TEAM_PERSON). The Person-table is not updated by this dao, so the persons in the team must be
 * persisted via a {@link no.kodemaker.ps.jdbiapp.repository.PersonDao}.
 *
 * @author Per Spilling
 */
public class TeamDaoJdbi implements TeamDao {
  public static class TeamTableCreator extends TableCreatorBase {
    public TeamTableCreator() {
      super(TeamDao.TEAM_TABLE_NAME, TeamDao.createTeamTableSql_postgres);
    }
  }

  public static class TeamPersonTableCreator extends TableCreatorBase {
    public TeamPersonTableCreator() {
      super(TeamPersonDao.TEAM_PERSON_TABLE_NAME, TeamPersonDao.createTeamPersonMappingTableSql);
    }
  }

  private JdbiHelper jdbiHelper = new JdbiHelper();
  private final DBI dbi = jdbiHelper.getDBI();

  // Let DBI manage the db connections
  private TeamDao teamDao = dbi.onDemand(TeamDao.class);
  private TeamPersonDao teamPersonDao =
      dbi.onDemand(TeamPersonDao.class); // team->person mapping table
  private PersonDao personDaoJdbi;

  public TeamDaoJdbi(PersonDao personDaoJdbi) {
    this.personDaoJdbi = personDaoJdbi;
  }

  @Override
  public Team save(final Team team) {
    long id;
    if (team.getId() == null) {
      id = insertWithTxCallback(team);
    } else {
      id = update(team);
    }
    return get(id);
  }

  private long update(final Team team) {
    // Must update 2 tables here, so will do this in a transaction
    return dbi.inTransaction(
        new TransactionCallback<Long>() {
          @Override
          public Long inTransaction(Handle conn, TransactionStatus status) throws Exception {
            // attach the dao's to the same handle
            TeamDao teamDao = conn.attach(TeamDao.class);
            TeamPersonDao teamPersonDao = conn.attach(TeamPersonDao.class);
            if (team.getPointOfContact() != null) {
              teamDao.updateWithPoC(team);
            } else {
              teamDao.updateWithoutPoC(team);
            }
            for (Person p : team.getMembers()) {
              // update the team->person mapping table
              TeamPerson tp = new TeamPerson(team.getId(), p.getId());
              if (!teamPersonDao.findByTeamId(team.getId()).contains(tp)) {
                teamPersonDao.insert(tp);
              }
            }
            return team.getId();
          }
        });
  }

  public long insertWithTxCallback(final Team team) {
    return dbi.inTransaction(
        new TransactionCallback<Long>() {
          @Override
          public Long inTransaction(Handle handle, TransactionStatus status) throws Exception {
            long teamId;
            /**
             * Notice that the onDemand dao's are not used here, but instead new instances are
             * created and attached to the same handle so that they will execute in the same TX.
             */
            TeamDao teamDao = handle.attach(TeamDao.class);
            TeamPersonDao teamPersonDao = handle.attach(TeamPersonDao.class);
            if (team.getPointOfContact() != null) {
              teamId = teamDao.insertWithPoC(team);
            } else {
              teamId = teamDao.insertWithoutPoC(team);
            }
            for (Person p : team.getMembers()) {
              // update the team->person mapping table
              teamPersonDao.insert(new TeamPerson(teamId, p.getId()));
            }
            // add test code for checking that TX is handled correctly
            checkIfTxShouldBeRolledBack(team);
            return teamId;
          }
        });
  }

  public Team insertWithTxHandle(final Team team) {
    // in this case we use an explicit handle, and attach the dao's to the same handle (connection)
    try (Handle handle = jdbiHelper.getTxHandle()) {
      handle.begin();
      TeamDao teamDao = handle.attach(TeamDao.class);
      TeamPersonDao teamPersonDao =
          handle.attach(TeamPersonDao.class); // team->person mapping table

      long teamId;
      if (team.getPointOfContact() != null) {
        teamId = teamDao.insertWithPoC(team);
      } else {
        teamId = teamDao.insertWithoutPoC(team);
      }
      for (Person p : team.getMembers()) {
        // update the team->person mapping table
        teamPersonDao.insert(new TeamPerson(teamId, p.getId()));
      }
      // add test code for checking that TX is handled correctly
      checkIfTxShouldBeRolledBack(team);
      handle.commit();
      return get(teamId);
    }
  }

  static void checkIfTxShouldBeRolledBack(Team team) {
    if (team.getName().equals("FAIL")) {
      throw new IllegalStateException("Name of team was FAIL");
    }
  }

  @Override
  public Team get(Long pk) {
    Team team = teamDao.get(pk);
    getTeamMembers(team, teamPersonDao, personDaoJdbi);
    return team;
  }

  @Override
  public int count() {
    return teamDao.count();
  }

  private void getTeamMembers(Team team, TeamPersonDao teamPersonDao, PersonDao personDao) {
    List<TeamPerson> teamPersonList = teamPersonDao.findByTeamId(team.getId());
    for (TeamPerson tp : teamPersonList) {
      team.addMember(personDao.get(tp.getPersonId()));
    }
  }

  @Override
  public Team findByName(String name) {
    List<Team> teamList = teamDao.findByName(name);
    if (teamList.size() > 0) {
      return get(teamList.get(0).getId());
    } else {
      return null;
    }
  }

  public List<Team> getAll() {
    List<Team> teams = teamDao.getAll();
    for (Team t : teams) {
      getTeamMembers(t, teamPersonDao, personDaoJdbi);
    }
    return teams;
  }

  @Override
  public boolean exists(Long id) {
    return get(id) != null;
  }

  @Override
  public void delete(Long id) {
    // delete associated entries from TEAM and TEAM_PERSON tables, but not from the PERSON table
    Team team = get(id);
    if (team == null) return;

    for (Person p : team.getMembers()) {
      teamPersonDao.delete(new TeamPerson(team.getId(), p.getId()));
    }
    teamDao.delete(team.getId());
  }

  /** Internal Team -> Person association dao */
  @RegisterMapper(TeamPersonMapper.class)
  interface TeamPersonDao extends Transactional<TeamPersonDao> {

    static final String TEAM_PERSON_TABLE_NAME = "TEAM_PERSON";

    static final String createTeamPersonMappingTableSql =
        "create table TEAM_PERSON ("
            + "teamId integer REFERENCES TEAM, "
            + "personId integer REFERENCES PERSON, "
            + "PRIMARY KEY (teamId, personId) );";

    @SqlUpdate("insert into TEAM_PERSON (teamId, personId) values (:tp.teamId, :tp.personId)")
    @GetGeneratedKeys
    long insert(@BindBean("tp") TeamPerson teamPerson);

    @SqlQuery("select * from TEAM_PERSON where teamId = :teamId")
    List<TeamPerson> findByTeamId(@Bind("teamId") Long teamId);

    @SqlUpdate("delete from TEAM where teamId = :tp.teamId and personId = :tp.personId")
    void delete(@BindBean("tp") TeamPerson teamPerson);
  }

  /** Generated JDBI DAO for the {@link Team} class. */
  @RegisterMapper(TeamMapper.class)
  interface TeamDao {
    static String TEAM_TABLE_NAME = "TEAM";

    static String createTeamTableSql_postgres =
        "create table TEAM ("
            + "teamId serial PRIMARY KEY, "
            + "name varchar(80) NOT NULL, "
            + "pocPersonId integer REFERENCES PERSON (personId), "
            + "unique(name))";

    @SqlUpdate(
        "insert into TEAM (teamId, name, pocPersonId) values (default, :t.name, :t.pointOfContactId)")
    @GetGeneratedKeys
    long insertWithPoC(@BindBean("t") Team team);

    @SqlUpdate("insert into TEAM (teamId, name, pocPersonId) values (default, :t.name)")
    @GetGeneratedKeys
    long insertWithoutPoC(@BindBean("t") Team team);

    @SqlUpdate(
        "update TEAM set name = :t.name,  pocPersonId = :t.pointOfContactId where teamId = :t.id")
    void updateWithPoC(@BindBean("t") Team team);

    @SqlUpdate("update TEAM set name = :t.name where teamId = :t.id")
    void updateWithoutPoC(@BindBean("t") Team team);

    @SqlQuery("select * from TEAM where teamId = :id")
    Team get(@Bind("id") long id);

    @SqlQuery("select count(*) from TEAM")
    int count();

    @SqlQuery("select * from TEAM where name like :name")
    List<Team> findByName(@Bind("name") String name);

    @SqlQuery("select * from TEAM")
    List<Team> getAll();

    @SqlUpdate("delete from TEAM where teamId = :id")
    void delete(@Bind("id") long id);
  }
}