Сохранять значение объекта, когда оно установлено - PullRequest
1 голос
/ 03 мая 2011

Я совершенно новичок в JPA + Hibernate + Spring (но у меня довольно большой опыт работы со средой Spring для веб-приложений и SQL), поэтому мой вопрос здесь, возможно, не в использовании правильного технического термина в JPA.

У меня есть типичный User POJO, помеченный javax.persistence.*, и я настроил hibernate + hsqldb в соответствии с найденными примерами, которые в настоящее время работают нормально.Класс User выглядит следующим образом:

@Entity
@Table(name = "USER")
public class User {

    private Long id;
    private String name;
    // Ignore id getter and setter methods

    @Column(name = "USER_NAME")
    public String getName() {
        return name;
    }

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

}

Это мой класс UserDAOImpl.

public class UserDAOImpl implements UserDAO {

    private HibernateTemplate hibernateTemplate;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.hibernateTemplate = new HibernateTemplate(sessionFactory);
    }

    @Override
    public void saveUser(User user) {
        hibernateTemplate.saveOrUpdate(user);
    }

    // This method is made to return only one User object.
    @Override
    @SuppressWarnings("unchecked")
    public User getGiUser() {
        return hibernateTemplate.find("from User where User_Name ='gi'").get(0);
    }
}

Используя метод getGiUser, я могу получить постоянный объект избаза данных (если я правильно понимаю).Мой вопрос заключается в том, можно ли сделать метод User.setName() для немедленной фиксации в базе данных при его вызове без необходимости сохранять его вручную?Как или где мне начать или узнать об этом?

Ответы [ 3 ]

2 голосов
/ 03 мая 2011

Из того, что я видел, вы ищете служебный компонент, который вызывает UserDAO:

public class UserServiceImpl implements UserService {
    private UserDAO userDao;    // injected by Spring

    @Transactional
    public void changeUserName(String name) {
        User user = userDao.getGiUser();
        user.setName(name);
        // I can't remember if this saveUser() call is required, or if
        // Hibernate will automatically pick up the changes and save the 
        // user object
        userDao.saveUser(user);
    }
}

@ Транзакционный отсюда:

http://static.springsource.org/spring/docs/current/spring-framework-reference/html/transaction.html

Кроме того, использование HibernateTemplate больше не является предпочтительным способом использования Hibernate. В этой части документации Spring показано, как использовать прямой код Hibernate:

http://static.springsource.org/spring/docs/current/spring-framework-reference/html/orm.html

Однако вы можете предпочесть использовать Hibernate в качестве поставщика JPA 2 в Spring; глава ORM (выше) также показывает, как интегрировать JPA с Spring. Hibernate все еще может оставаться вашим провайдером JPA 2. Таким образом вы отделяете весь свой код от Spring и Hibernate и просто используете стандартные аннотации JPA 2 с EntityManager.

1 голос
/ 03 мая 2011

Когда вы получаете пользователя из сеанса (с session.get(), session.load(), обходом ассоциации или запросом HQL или Criteria), любое изменение, внесенное в пользователя, будет зафиксировано, когда будет совершена окружающая транзакция (без каких-либо вызов save, update, saveOrUpdate или merge необходимо). Он не будет записан в базу данных (сброшен) немедленно, но будет при необходимости: перед фиксацией или перед выполнением запроса, результат которого может зависеть от сброса. Вам обычно не нужно заботиться.

Если под «зафиксировано в базе данных» вы имеете в виду фиксацию в терминах транзакции, то это невозможно. Изменения фиксируются, когда фиксируется окружающая транзакция.

Если вы хотите, чтобы конкретное обновление было зафиксировано за пределами текущей транзакции, вам необходимо выполнить обновление в другой транзакции, используя код, такой как код в ответе BobG, но помеченный @Transactional(propagation = Propagation.REQUIRES_NEW).

Может быть, вам следует объяснить более точно, что вы хотите сделать и почему вы хотите это сделать.

1 голос
/ 03 мая 2011

Вы можете использовать механизм перехвата для достижения этой цели. Правда заключается в том, что изменения должны быть сохранены где-то вдоль строки, но ваш класс User не подходит для этого, поэтому вы можете написать код где-то еще и использовать механизм перехвата или Aspect Oriented, используя среду приложения, такую ​​как Spring. для отслеживания вызываемых методов и при каждом вызове определенного метода (например, setName) сохраняйте состояние вашего класса.

Вот пример гибернации и весенней интеграции

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...