gpt4 book ai didi

java - @PrePersist 正在被调用并修改实体,但没有写入数据库

转载 作者:可可西里 更新时间:2023-11-01 07:09:46 25 4
gpt4 key购买 nike

我正在使用 Hibernate 和 MySQL 在 Spring MVC 中开发一个应用程序,但我遇到了一个问题。我正在尝试使用 @PrePersist 注释在我的 Java 实体中填充我最后修改的字段。我已经调试了代码,正在调用方法并设置值。但是,数据库引发了空冲突,因为它没有写出 @PrePersist 方法添加的值。有谁知道如何解决这个问题,将数据写入数据库?

仅供引用,除了更改日期外,我还想使用这些 JPA 注释来执行某些业务逻辑或使用与注释类似的东西。

代码:

@Entity
@Table(name = "account")
public class Account {
@Column(name = "modified_on")
@Temporal(TemporalType.TIMESTAMP)
@DateTimeFormat(style = "MM")
@NotNull()
private Calendar modifiedOn;
... getters, setter and other stuff

@PrePersist
public void prePersist() {
Calendar now = Calendar.getInstance();
this.createdOn = now;
this.modifiedOn = now;
}


@PreUpdate
public void preUpdate() {
Calendar now = Calendar.getInstance();
this.modifiedOn = now;
}

applicationContext-Persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<repositories base-package="${repositoryPackageName}" />
<beans:bean id="hibernateJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
<beans:bean id="exceptionTranslator" class="org.springframework.orm.hibernate4.HibernateExceptionTranslator" />
<beans:bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<beans:property name="entityManagerFactory" ref="entityManagerFactory" />
</beans:bean>
<beans:bean id="persistenceExceptionTranslationPostProcessor" class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<beans:property name="driverClassName" value="${database.driverClassName}" />
<beans:property name="url" value="${database.url}" />
<beans:property name="username" value="${database.username}" />
<beans:property name="password" value="${database.password}" />
</beans:bean>
<beans:bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter" />
<beans:property name="packagesToScan" value="${scanPackageName}" />
<beans:property name="jpaProperties">
<beans:props>
<beans:prop key="hbm2ddl.auto">validate</beans:prop>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</beans:prop>
<beans:prop key="hibernate.query.substitutions">true '1', false '0'</beans:prop>
<beans:prop key="hibernate.generate_statistics">true</beans:prop>
<beans:prop key="hibernate.show_sql">false</beans:prop>
<beans:prop key="hibernate.format_sql">true</beans:prop>
<beans:prop key="hibernate.hbm2ddl.auto">validate</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
</beans:beans>

applicationContext.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation=
"http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.2.xsd"
>
<context:property-placeholder location="classpath:META-INF/spring/*.properties" />
<context:property-placeholder location="classpath:META-INF/properties/*.properties"/>
<context:component-scan base-package="${doaminPackageName}"/>
<context:component-scan base-package="${repositoryPackagename}"/>
<context:component-scan base-package="${repositoryPackageName}" >
<context:exclude-filter type="custom" expression="ourapp.util.TestClassFilter"/>
</context:component-scan>
<context:component-scan base-package="${utilBeanPackageName}"/>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="${mail.server.host}" />
<property name="port" value="${mail.server.port}" />
<property name="protocol" value="${mail.server.protocol}" />
<property name="username" value="${mail.server.username}" />
<property name="password" value="${mail.server.password}" />
<property name="javaMailProperties">
<util:properties location="classpath:META-INF/spring/javamail.properties" />
</property>
</bean>
</beans>

applicationContext-web.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"

xsi:schemaLocation=
"http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.2.xsd"
>
<context:component-scan base-package="${controllerPackageName}"/>
<mvc:annotation-driven/>
<mvc:default-servlet-handler/>

<mvc:resources location="/, classpath:/META-INF/web-resources/" mapping="/resources/**"/>

<mvc:interceptors>
<bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor"/>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="lang"/>
</mvc:interceptors>
<mvc:view-controller path="/uncaughtException"/>
<mvc:view-controller path="/resourceNotFound"/>
<mvc:view-controller path="/dataAccessFailure"/>

<bean class="org.springframework.context.support.ReloadableResourceBundleMessageSource" id="messageSource" p:fallbackToSystemLocale="false">
<property name="basenames">
<list>
<value>META-INF/web-resources/i18n/accountCreation/messages</value>
<value>META-INF/web-resources/i18n/accountCreation/application</value>
<value>META-INF/web-resources/i18n/accountCreation/errors</value>
<!-- Keep Global resource bundles at the bottom, they are checked last -->
<value>META-INF/web-resources/i18n/global_messages</value>
<value>META-INF/web-resources/i18n/global_application</value>
<value>META-INF/web-resources/i18n/global_errors</value>
</list>
</property>
</bean>
<bean class="org.springframework.web.servlet.i18n.CookieLocaleResolver" id="localeResolver" p:cookieName="locale">
<property name="defaultLocale" value="en"/>
</bean>
<bean class="org.springframework.ui.context.support.ResourceBundleThemeSource" id="themeSource"/>
<bean class="org.springframework.web.servlet.theme.CookieThemeResolver" id="themeResolver" p:cookieName="theme" p:defaultThemeName="standard"/>
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" p:defaultErrorView="exceptions/uncaughtException">
<property name="exceptionMappings">
<props>
<prop key=".DataAccessException">exceptions/dataAccessFailure</prop>
<prop key=".NoSuchRequestHandlingMethodException">exceptions/resourceNotFound</prop>
<prop key=".TypeMismatchException">exceptions/resourceNotFound</prop>
<prop key=".MissingServletRequestParameterException">exceptions/resourceNotFound</prop>
</props>
</property>
</bean>

<!-- Enable this for integration of file upload functionality -->
<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver"/>
<!-- TymeLeaf Settings -->
<!-- THYMELEAF: Template Resolver for webapp pages -->
<bean class="org.thymeleaf.templateresolver.ServletContextTemplateResolver" id="templateResolver">
<property name="prefix" value="/WEB-INF/templates/"/>
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML5"/>
</bean>
<!-- THYMELEAF: Template Engine (Spring3-specific version) -->
<bean class="org.thymeleaf.spring3.SpringTemplateEngine" id="templateEngine">
<qualifier value="templateEngine"/>
<property name="templateResolver" ref="templateResolver"/>
</bean>
<!-- THYMELEAF: View Resolver - implementation of Spring's ViewResolver interface -->
<bean class="org.thymeleaf.spring3.view.ThymeleafViewResolver">
<property name="templateEngine" ref="templateEngine"/>
</bean>
</beans>

最佳答案

如果您的应用程序被配置为连接到 JPA 实体的方法中,如果您直接设置字段,它可能不会跟踪更改。尝试使用 setter 方法:

@PrePersist
public void prePersist() {
Calendar now = Calendar.getInstance();
this.setCreatedOn(now);
this.setModifiedOn(now);
}


@PreUpdate
public void preUpdate() {
Calendar now = Calendar.getInstance();
this.setModifiedOn(now);
}

此外,如 a simily question 的回答中所述,这些注释行为是依赖于实现的:

Note that it is implementation-dependent as to whether PreUpdate and PostUpdate call- backs occur when an entity is persisted and subsequently modified in a single transaction or when an entity is modified and subsequently removed within a single transaction. Portable applications should not rely on such behavior.

所以这可能取决于您如何加载和保留您的实体。

关于java - @PrePersist 正在被调用并修改实体,但没有写入数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18884639/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com