2017-01-25 14 views
1

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


Пример, чтобы лучше проиллюстрировать точку, показан ниже.

  • Класс MyEntity представляет собой объект.
  • Класс MyEntityRepository - это Spring Data Repository, используемый для взаимодействия с базами данных для объекта MyEntity.
  • Класс MyService имеет транзакционный метод, называемый save, который сравнивает новую версию MyEntity (называемую entity) с oldEntity. Если entity и oldEntity различны, то entity сохраняется в базе данных; в противном случае он не сохраняется.

oldEntity извлекается из хранилища и сравнивается с entity. Однако, когда это делается, oldEntity является всегда так же, как entity. (Измененные значения в entity отражаются в oldEntity.)

Поскольку entity еще не сохранен, как я могу принести состояние субъекта, как она существует в настоящее время в базе данных, а не в текущем контексте? Возможно ли использование аннотаций Spring или установка значения распространения для выхода за пределы текущего контекста персистентности для извлечения объекта таким образом, чтобы оно было реальным, сохраняемым значением, а не тем, что в текущем контексте?


@Service 
public class MyService { 
    @Autowire 
    private MyEntityRepository repository; 

    @Transactional 
    public boolean save(MyEntity entity) { 
     MyEntity oldEntity = repository.findOne(entity.getId()); 
     if (entity.compareTo(oldEntity) != 0) { 
      repository.save(entity); 
     } 
    } 
} 

public interface MyEntityRepository extends PagingAndSortingRepository<MyEntity, Long> { 
    MyEntity findByName(String name); 
} 

@Entity 
public class MyEntity { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    protected Long id; 

    @Column(nullable = false) 
    protected String name; 

    public Long getId() { ... } 
    public void setId(Long id) { ... } 
    public String getName() { ... } 
    public void setName(String name) { ... } 
    public int compareTo(MyEntity entity) { ... } 

} 
+0

Что такое прецедент для этого? – MarkOfHall

+0

В зависимости от вашего провайдера может возникнуть флеш, когда запрос, который должен выполняться, зависит от новых или обновленных объектов в текущем контексте сохранения. Это объясняет то, что вы видите - ваш поставщик сбрасывает ожидающие изменения, чтобы обеспечить согласованность запроса, который должен быть выпущен. O –

+0

@MarkOfHall В моем конкретном примере использования вызывается дополнительная обработка, если и только если один из нескольких атрибутов сущностей изменился. В результате я хотел бы получить сохраненное состояние объекта и сравнить его с измененным состоянием объекта. – whyceewhite

ответ

0

Вы должны иметь в виду поведение как транзакции работают с юридическими лицами. Когда вы сделаете MyEntity entity = myEntityRepository.findByName("test"); И вызовите что-то вроде entity.setName(); внутри транзакции, после того как транзакция будет завершена, столбец имен в базе данных будет обновлен. Вам нужно будет использовать диспетчер сущностей для удаления объекта в транзакции до вызова setName, чтобы остановить обновление базы данных. Но тогда вам нужно будет повторно добавить его, если вы хотите сохранить изменения в имени.