我的Spring Boot应用程序中有两个实体:
用户:
public class User implements java.io.Serializable, UserDetails {
@GenericGenerator(name = "generator", strategy = "foreign", parameters = @Parameter(name = "property", value = "person") )
@Id
@GeneratedValue(generator = "generator")
@Column(name = "person_id", unique = true, nullable = false)
public int getPersonId() {
return this.personId;
}
public void setPersonId(int personId) {
this.personId = personId;
}
@OneToOne(fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn
public Person getPerson() {
return this.person;
}
public void setPerson(Person person) {
this.person = person;
}
@Column(name = "email", unique = true, nullable = false, length = 50)
public String getEmail() {
return this.email;
}
public void setLoginVersuche(int loginVersuche) {
this.loginVersuche = loginVersuche;
}
@Column(name ="loginVersuche")
public int getLoginVersuche() {
return loginVersuche;
}
...omitted code...
}
和人:
public class Person implements java.io.Serializable {
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "idPerson", unique = true, nullable = false)
public Integer getIdPerson() {
return this.idPerson;
}
public void setIdPerson(Integer idPerson) {
this.idPerson = idPerson;
}
@OneToOne(fetch = FetchType.LAZY, mappedBy = "person")
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
...omitted code...
}
我有我的DAO:
@Repository
public interface UserDAO extends CrudRepository<User, Integer>{
User findByEmail(String user);
}
现在我想更新身份验证中的字段。为此,我要求User对象(电子邮件是唯一的)并设置字段。在此之后我想更新db:
中的对象User userByDB = userDAO.findByEmail(username);
userByDB.setLoginVersuche(userByDB.getLoginVersuche()+1);
userDAO.save(userByDB);
它只是不更新db中的数据字段,但我也没有收到任何错误。是否与用户外键中的主键有关?
UPDATE-1
@Transactional
@Modifying
@Query("update User u set u.loginVersuche = u.loginVersuche+1, u.gesperrt = ?1 where u.email = ?2")
public int incrementLoginVersuche(boolean gesperrt, String email);
UPDATE-2
23:51:43.181 TRACE org.springframework.transaction.support.TransactionSynchronizationManager - 初始化事务同步 23:51:43.182 TRACE org.springframework.transaction.interceptor.TransactionInterceptor - 获取[org.springframework.data.jpa.repository.support.SimpleJpaRepository.incrementLoginVersuche]的事务 23:51:43.183 DEBUG org.springframework.orm.jpa.EntityManagerFactoryUtils - 打开JPA EntityManager 23:51:43.184 TRACE org.hibernate.internal.SessionFactoryImpl $ SessionBuilderImpl - 打开Hibernate会话。 tenant = null,owner = land.hibernate.jpa.internal.EntityManagerImpl@71dfe394 23:51:43.184 TRACE org.hibernate.internal.SessionImpl - 时间戳打开的会话:14569591031 23:51:43.185 TRACE org.hibernate.internal.SessionImpl - 将刷新模式设置为:AUTO 23:51:43.186 TRACE org.hibernate.internal.SessionImpl - 将缓存模式设置为:NORMAL 23:51:43.189 DEBUG org.springframework.orm.jpa.EntityManagerFactoryUtils - 为JPA EntityManager注册事务同步 23:51:43.207 TRACE org.springframework.transaction.support.TransactionSynchronizationManager - 结合的值[org.springframework.orm.jpa.EntityManagerHolder@1028e769用于键[org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@3d018d7d]线程[HTTP -NiO-8443-EXEC-2] 23:51:43.208 TRACE org.hibernate.engine.query.spi.QueryPlanCache - 位于缓存中的HQL查询计划(更新用户u set u.loginVersuche = u.loginVersuche + 1,u.gesperrt =?1其中u.email = ?2) 23:51:43.210 TRACE org.springframework.transaction.support.TransactionSynchronizationManager - 检索到的值[org.springframework.orm.jpa.EntityManagerHolder@1028e769用于键[org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@3d018d7d]结合到线程[ HTTP-NIO-8443-EXEC-2] 23:51:43.214 DEBUG org.hibernate.jpa.spi.AbstractEntityManagerImpl - 标记回滚事务 23:51:43.215 TRACE org.springframework.transaction.interceptor.TransactionInterceptor - 异常后完成[org.springframework.data.jpa.repository.support.SimpleJpaRepository.incrementLoginVersuche]的事务:javax.persistence.TransactionRequiredException:执行更新/删除询问 23:51:43.217 TRACE org.springframework.transaction.interceptor.RuleBasedTransactionAttribute - 应用规则来确定事务是否应该在javax.persistence.TransactionRequiredException上回滚:执行更新/删除查询
UPDATE-3
TransactionManager配置:
@Bean(name = "transactionManager")
public PlatformTransactionManager txManager() {
return new DataSourceTransactionManager(dataSource());
}
答案 0 :(得分:1)
根据docs (4.6. Transactionality)
默认情况下,存储库实例上的CRUD方法是事务性的
因此您不需要在@Transactional(readOnly = true)
界面上方添加UserDAO
注释。
相反,您应该使您的保存方法具有事务性(假设您的类是有效的Spring组件):
@Transactional
public void incrementVersuche() {
...
User userByDB = userDAO.findByEmail(username);
userByDB.setLoginVersuche(userByDB.getLoginVersuche()+1);
userDAO.save(userByDB);
}
<强>更新强>
public interface IUserSaver {
void incrementVersucheAndSave(String username)
}
@Service
public class UserSaver implements IUserSaver {
@Transactional
public void incrementVersucheAndSave(String username) {
User userByDB = userDAO.findByEmail(username);
userByDB.setLoginVersuche(userByDB.getLoginVersuche()+1);
userDAO.save(userByDB);
}
}
然后在你的AuthProvider中:
....
@Autowired
private IUserSaver saver;
public void incrementLoginVersuche() {
....
saver.incrementVersucheAndSave(username);
}
答案 1 :(得分:0)
答案 2 :(得分:0)
没有事务调用的方法。检查你的tr demercations或来电环境。不是事务性的。原始问题:如果设置tr RO,它将不会执行更新SQL命令。