Отображение DTO и обновление базы данных с помощью Java, Dozer и Hibernate

Я использую Dozer для сопоставления сущностей Hibernate с их DTO. Вот упрощенный пример класса:

@Entity
public class Role {

     @Id
     @GeneratedValue
     @Column(name="RoleId", nullable=false)
     public int roleId;

     @Column(name="RoleName", nullable=false)
     @NotEmpty
     public String roleName;

     //get + set  (not for the roleId since its autogenerated)
}

   public class RoleDTO {   

     private int roleId;
     private String roleName;

     public RoleDTO(int roleId, String roleName) {
          this.roleId = roleId;
          this.roleName = roleName;
     }

     public RoleDTO() {}

     //gets + sets
  }

Теперь сопоставление работает нормально, но у меня проблема при попытке выполнить обновление. Допустим, у меня есть роль (1, «Администратор») в моей базе данных. Мое представление сначала генерирует DTO с обновленными полями:

RoleDTO roleDTO = new RoleDTO(1, "admin");

В конце концов класс, который сохраняет роль, получает DTO и преобразует его в класс Entity через Dozer, чтобы сохранить изменения:

Role role = DozerMapper.map(roleDTO,Role.class);    

На этом этапе моя сущность роли потеряла свой идентификатор, предположительно из-за того, что столбец идентификатора определен как автоинкремент, и я, очевидно, не могу обновить сущность с нулевым идентификатором.

Итак, как мне подойти к этой проблеме, чтобы идентификатор и обновленные поля были сопоставлены с сущностью? Я всегда мог перенести объект entity с помощью hibernate и обновить каждое из его полей полями из DTO и сохранить его обратно, но это нарушило бы всю цель использования Dozer.

Спасибо за любую помощь.


person Endo    schedule 29.03.2011    source источник
comment
Что ж, простым решением было бы добавить метод setID к классу Entity и установить это значение вручную. Для меня это выглядит неоптимальным подходом, хотя лучше, чем копирование каждого поля.   -  person Endo    schedule 29.03.2011


Ответы (3)


В этом случае вполне допустимый подход - предоставить сеттер для вашего roleId в сущности Role. Затем Dozer также установит идентификатор. (Кроме того, я предполагаю, что ваши поля на Role не являются общедоступными.)

С Dozer вы создаете объект из DTO. В этот момент объект отсоединяется, то есть не связан с сеансом Hibernate. Затем вы должны использовать session.merge(role), чтобы сохранить изменения.

person Michal Bachman    schedule 31.03.2011

        @Autowired
        private RoleDao roleDao;

        @Transactional(readOnly = false)
        public void updateRole(RoleDTO roleDTO) {
            Role role = beanMapper.map(roleDTO, Role.class);
            roleDao.update(role);
        }   

Вы можете создать класс Role Dao и сделать ссылку в классе менеджера, где вы выполняете сопоставление, и сделать метод обновления для обновления вашего класса Role в GenericDao, где вы определили метод обновления спящего режима, вызовите его, и ваша работа будет выполнена.

person pankaj    schedule 23.04.2014

Вам не нужно выполнять слияние. Dozer позволит вам применить изменения к объекту.

Role role = <entitymangaer>.find("id", Role.class);   
role = beanMapper.map(dto, role);
role.update();
person Paul Johnson    schedule 05.05.2016