Свойства сущности не меняются после вызова dao.findByID(id)

Вопрос здесь в том, почему свойства объекта не сохраняются после вызова некоторых сеттеров объекта. Обычно при изменении свойства управляемого объекта оно должно распространяться на базу данных.

Взгляните на этот пример:

@Service
public class SystemServiceImpl implements SystemService {

@Autowired
private SystemDao systemDao;


@Override
@Transactional
public System replace(Long systemID) {

    // External system to replace
    System system = systemDao.findByID(systemID);
    if (null != system) {
        system.setName("Test"); // Calling findByID again shows that this call did not have any effect.
    }
    return system;
}

}

-

@Entity
@Table(name = "db.system")
public class System {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long systemID;

private String name;

@OneToMany(mappedBy = "system", fetch = FetchType.LAZY)
@JsonIgnore
private List<Customer> customers = new ArrayList<Customer>();

public Long getSystemID() {
    return systemID;
}

public void setSystemID(Long systemID) {
    this.systemID = systemID;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public List<Customer> getCustomers() {
    return customers;
}

public void setCustomers(List<Customer> customers) {
    this.customers = customers;
}
}

Если я вызываю systemDao.merge после system.setName("Test"), то он сохраняется в базе данных. Я чувствую, что мне не нужно вызывать слияние, поскольку это должен быть управляемый объект.

Я пробовал использовать метод замены как с @Transactional, так и без него, и оба они дают одинаковый результат.

Любые идеи?

Спасибо,


person Feras Wilson    schedule 27.09.2017    source источник
comment
можете ли вы добавить класс @entity, особенно определение столбцов, которые не вызывают запуск обновления   -  person Maciej Kowalski    schedule 27.09.2017
comment
также не является ли этот метод замены частью какого-либо транзакционного метода более высокого уровня?   -  person Maciej Kowalski    schedule 27.09.2017
comment
обновил ответ, также метод замены является настраиваемым методом, существующим только в созданном мной интерфейсе.   -  person Feras Wilson    schedule 27.09.2017
comment
Вы звоните .save()? Я не думаю, что без вызова .save() или любого другого связанного метода БД будет обновлена.   -  person Vikas Prasad    schedule 27.09.2017
comment
Не могли бы вы предоставить нам класс DAO?   -  person Nikolas Charalambidis    schedule 27.09.2017
comment
Афаик, вам не нужно вызывать сохранение, если оно управляемое.   -  person Feras Wilson    schedule 27.09.2017
comment
Я ничего не знаю об этом. Хотелось бы прочитать об этом. У вас есть ссылки?   -  person Vikas Prasad    schedule 27.09.2017
comment
Дао - это индивидуальный класс. Здесь важно то, почему Entity не обновляется.   -  person Feras Wilson    schedule 27.09.2017
comment
Здесь: если X является управляемым объектом, он игнорируется операцией слияния, однако операция слияния каскадируется на объекты, на которые ссылаются отношения из X, если эти отношения были аннотированы значением каскадного элемента аннотации cascade=MERGE или cascade=ALL. .   -  person Feras Wilson    schedule 27.09.2017
comment
Непосредственно перед нулевой проверкой после получения system запустите systemDao.save(system) (не после внесения изменений в system) и дайте мне знать, сохранились ли изменения.   -  person Vikas Prasad    schedule 27.09.2017
comment
@VikasPrasad systemDao.merge(система); не имеет никакого значения, если вызывается перед оператором if.   -  person Feras Wilson    schedule 27.09.2017
comment
Или во второй раз вместо findByID(systemID) попробовать только findByName('test')?   -  person Vikas Prasad    schedule 27.09.2017
comment
Давайте продолжим обсуждение в чате.   -  person Vikas Prasad    schedule 27.09.2017
comment
цитируя ответ в stackoverflow.com/questions/24788484/ : Важным моментом здесь является то, что добавление объекта в контекст сохранения не обязательно быть равным хранящемуся в базе данных. Поставщик постоянства может отложить взаимодействие с базой данных, если сочтет это целесообразным.   -  person Vikas Prasad    schedule 27.09.2017


Ответы (2)


arrow_upward
0
arrow_downward

Поведение можно объяснить, если SystemDao.findByID() возвращает отсоединенный объект. Убедитесь, что SystemDao не использует RequiresNew-Transaction и не отсоединяет объект явно после его загрузки. Было бы очень полезно, если бы вы разместили код SystemDao и любые соответствующие записи конфигурации (Spring, конфигурация диспетчера объектов, ...).

person Guenther    schedule 27.09.2017
comment
Почему сущность отсоединяется после findByID? Если это возможно, пожалуйста, укажите, как это может произойти. Может быть, пример конфигурации, которую я могу найти в своем исходном коде. - person Feras Wilson; 27.09.2017
comment
Объект может быть отсоединен, если вы явно отсоедините его em.detach(object) или вызовете em.clear(). Он также может стать отсоединенным, если код запускается в отдельной транзакции, как упоминалось выше. - person Guenther; 27.09.2017
comment
Я могу сказать вам, что мой дао расширяет HibernateDaoSupport. Я также использую Spring 3.2. - person Feras Wilson; 27.09.2017
comment
Без публикации вашего кода SystemDao и конфигурации мы не сможем вам помочь. Из того, что вы сказали выше, все указывает на то, что объект загружается в другой транзакции, а не является частью текущего сеанса при изменении. Кстати. Поддержка HibernateDaoSupport устарела. - person Guenther; 27.09.2017
comment
открытый интерфейс SystemDao расширяет HibernateDaoSupport‹System, Long› { System findByName(String name); } - person Feras Wilson; 27.09.2017

arrow_upward
0
arrow_downward

Ошибка происходила, когда я запускал свои интеграционные тесты. Оказывается, Transactional ничего не делает, потому что сеанса нет. Решением было добавить Transactional в мои тесты.

person Feras Wilson    schedule 11.10.2017