我正在使用Spring 3.0.5.RELEASE和Hibernate 3.6.1.Final。从MySql DB读取是可以的,但是当我尝试写入它时,我在日志中得到了这个:
22 mars 2011 22:37:34,625 DEBUG InjectionMetadata: Processing injected method of bean 'thoughtDao': PersistenceElement for protected javax.persistence.EntityManager com.prosveta.backend.daoimpl.GenericDaoImpl.entityManager
22 mars 2011 22:37:34,625 DEBUG DefaultListableBeanFactory: Returning cached instance of singleton bean 'entityManagerFactory'
22 mars 2011 22:37:34,625 DEBUG DefaultListableBeanFactory: Creating shared instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
22 mars 2011 22:37:34,625 DEBUG DefaultListableBeanFactory: Creating instance of bean 'org.springframework.transaction.config.internalTransactionAdvisor'
22 mars 2011 22:37:34,640 DEBUG DefaultListableBeanFactory: Eagerly caching bean 'org.springframework.transaction.config.internalTransactionAdvisor' to allow for resolving potential circular references
22 mars 2011 22:37:34,656 DEBUG DefaultListableBeanFactory: Creating shared instance of singleton bean 'org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0'
22 mars 2011 22:37:34,656 DEBUG DefaultListableBeanFactory: Creating instance of bean 'org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0'
22 mars 2011 22:37:34,656 DEBUG DefaultListableBeanFactory: Eagerly caching bean 'org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0' to allow for resolving potential circular references
22 mars 2011 22:37:34,671 DEBUG DefaultListableBeanFactory: Finished creating instance of bean 'org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0'
22 mars 2011 22:37:34,671 DEBUG DefaultListableBeanFactory: Finished creating instance of bean 'org.springframework.transaction.config.internalTransactionAdvisor'
22 mars 2011 22:37:34,718 DEBUG DefaultListableBeanFactory: Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
22 mars 2011 22:37:34,734 DEBUG JdkDynamicAopProxy: Creating JDK dynamic proxy: target source is SingletonTargetSource for target object [com.prosveta.backend.daoimpl.thought.ThoughtDaoImpl@d337d3]
22 mars 2011 22:37:34,765 DEBUG DefaultListableBeanFactory: Finished creating instance of bean 'thoughtDao'
22 mars 2011 22:37:34,765 DEBUG DefaultListableBeanFactory: Returning cached instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
22 mars 2011 22:37:34,765 DEBUG DefaultListableBeanFactory: Returning cached instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
22 mars 2011 22:37:34,765 DEBUG DefaultListableBeanFactory: Returning cached instance of singleton bean 'org.springframework.context.annotation.internalRequiredAnnotationProcessor'
22 mars 2011 22:37:34,765 DEBUG DefaultListableBeanFactory: Returning cached instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
22 mars 2011 22:37:34,765 DEBUG DefaultListableBeanFactory: Returning cached instance of singleton bean 'org.springframework.context.annotation.internalPersistenceAnnotationProcessor'
22 mars 2011 22:37:34,765 DEBUG DefaultListableBeanFactory: Returning cached instance of singleton bean 'org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor#0'
22 mars 2011 22:37:34,765 DEBUG DefaultListableBeanFactory: Returning cached instance of singleton bean 'prosvetaDataSource'
22 mars 2011 22:37:34,765 DEBUG DefaultListableBeanFactory: Returning cached instance of singleton bean 'entityManagerFactory'
22 mars 2011 22:37:34,765 DEBUG DefaultListableBeanFactory: Returning cached instance of singleton bean 'org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor#0'
22 mars 2011 22:37:34,765 DEBUG DefaultListableBeanFactory: Creating shared instance of singleton bean 'transactionManager'
22 mars 2011 22:37:34,765 DEBUG DefaultListableBeanFactory: Creating instance of bean 'transactionManager'
22 mars 2011 22:37:34,796 DEBUG DefaultListableBeanFactory: Eagerly caching bean 'transactionManager' to allow for resolving potential circular references
22 mars 2011 22:37:34,796 DEBUG DefaultListableBeanFactory: Returning cached instance of singleton bean 'entityManagerFactory'
22 mars 2011 22:37:34,796 DEBUG DefaultListableBeanFactory: Invoking afterPropertiesSet() on bean with name 'transactionManager'
22 mars 2011 22:37:34,796 DEBUG DefaultListableBeanFactory: Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
22 mars 2011 22:37:34,812 DEBUG DefaultListableBeanFactory: Finished creating instance of bean 'transactionManager'
22 mars 2011 22:37:34,812 DEBUG DefaultListableBeanFactory: Returning cached instance of singleton bean 'org.springframework.aop.config.internalAutoProxyCreator'
22 mars 2011 22:37:34,812 DEBUG DefaultListableBeanFactory: Returning cached instance of singleton bean 'org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0'
22 mars 2011 22:37:34,812 DEBUG DefaultListableBeanFactory: Creating shared instance of singleton bean 'org.springframework.transaction.interceptor.TransactionInterceptor#0'
22 mars 2011 22:37:34,812 DEBUG DefaultListableBeanFactory: Creating instance of bean 'org.springframework.transaction.interceptor.TransactionInterceptor#0'
22 mars 2011 22:37:34,812 DEBUG DefaultListableBeanFactory: Eagerly caching bean 'org.springframework.transaction.interceptor.TransactionInterceptor#0' to allow for resolving potential circular references
22 mars 2011 22:37:34,812 DEBUG DefaultListableBeanFactory: Returning cached instance of singleton bean 'org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0'
22 mars 2011 22:37:34,812 DEBUG DefaultListableBeanFactory: Invoking afterPropertiesSet() on bean with name 'org.springframework.transaction.interceptor.TransactionInterceptor#0'
22 mars 2011 22:37:34,812 DEBUG DefaultListableBeanFactory: Finished creating instance of bean 'org.springframework.transaction.interceptor.TransactionInterceptor#0'
22 mars 2011 22:37:34,812 DEBUG DefaultListableBeanFactory: Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
22 mars 2011 22:37:34,812 DEBUG DefaultListableBeanFactory: Creating shared instance of singleton bean 'thoughtDaoBean'
22 mars 2011 22:37:34,828 DEBUG DefaultListableBeanFactory: Creating instance of bean 'thoughtDaoBean'
22 mars 2011 22:37:34,828 DEBUG DefaultListableBeanFactory: Eagerly caching bean 'thoughtDaoBean' to allow for resolving potential circular references
22 mars 2011 22:37:34,828 DEBUG InjectionMetadata: Processing injected method of bean 'thoughtDaoBean': PersistenceElement for protected javax.persistence.EntityManager com.prosveta.backend.daoimpl.GenericDaoImpl.entityManager
22 mars 2011 22:37:34,828 DEBUG DefaultListableBeanFactory: Returning cached instance of singleton bean 'entityManagerFactory'
22 mars 2011 22:37:34,828 DEBUG DefaultListableBeanFactory: Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
22 mars 2011 22:37:34,828 DEBUG JdkDynamicAopProxy: Creating JDK dynamic proxy: target source is SingletonTargetSource for target object [com.prosveta.backend.daoimpl.thought.ThoughtDaoImpl@1f2af1c]
22 mars 2011 22:37:34,828 DEBUG DefaultListableBeanFactory: Finished creating instance of bean 'thoughtDaoBean'
22 mars 2011 22:37:34,828 DEBUG ClassPathXmlApplicationContext: Unable to locate LifecycleProcessor with name 'lifecycleProcessor': using default [org.springframework.context.support.DefaultLifecycleProcessor@a36b53]
22 mars 2011 22:37:34,828 DEBUG DefaultListableBeanFactory: Returning cached instance of singleton bean 'lifecycleProcessor'
22 mars 2011 22:37:34,828 DEBUG DefaultListableBeanFactory: Returning cached instance of singleton bean 'thoughtDaoBean'
22 mars 2011 22:37:34,859 DEBUG SharedEntityManagerCreator$SharedEntityManagerInvocationHandler: Creating new EntityManager for shared EntityManager invocation
22 mars 2011 22:37:34,968 DEBUG SessionImpl : opened session at timestamp: 5328199085629440
22 mars 2011 22:37:35,031 DEBUG AbstractSaveEventListener: delaying identity-insert due to no transaction in progress
22 mars 2011 22:37:35,031 DEBUG EntityManagerFactoryUtils: Closing JPA EntityManager
使用 AbstractSaveEventListener:由于没有正在进行的事务而延迟身份插入在结束前一行。
我一直在寻找很长时间,将我的Spring配置文件与网上的其他人进行比较,但没有结果。
以下是配置文件:
mysql连接器
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.15</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
的persistence.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="prosvetaPersistenceUnit"
transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.prosveta.backend.model.thought.Thought</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<!--
value='create' to build a new database on each run;
value='update' to modify an existing database;
value='create-drop' means the same as 'create' but also drops tables when Hibernate closes;
value='validate' makes no changes to the database
-->
<property name="hibernate.hbm2ddl.auto" value="validate"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.cache.use_query_cache" value="true"/>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.SingletonEhCacheProvider"/>
<!--
<property name="hibernate.search.default.directory_provider" value="org.hibernate.search.store.FSDirectoryProvider"/>
<property name="hibernate.search.default.indexBase" value="./lucene/indexes"/>
<property name="hibernate.search.default.batch.merge_factor" value="10"/>
<property name="hibernate.search.default.batch.max_buffered_docs" value="10"/>
-->
</properties>
</persistence-unit>
</persistence>
弹簧jpa.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<!-- JPA Entity Manager Factory -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:dataSource-ref="prosvetaDataSource">
<property name="persistenceUnitName" value="prosvetaPersistenceUnit" />
</bean>
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<!-- Database LOB Handling -->
<!-- bean id="defaultLobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" / -->
<!-- Read in DAOs from the JPA package -->
<context:component-scan base-package="com.prosveta.backend.daoimpl" />
<!-- Transaction Config -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManagerFactory" />
<tx:annotation-driven mode="aspectj"
transaction-manager="transactionManager" />
</beans>
datasource.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
<!-- Basic DataSource -->
<bean id="prosvetaDataSource"
class="org.apache.commons.dbcp.BasicDataSource"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.url}"
p:username="${jdbc.username}"
p:password="${jdbc.password}"/>
</beans>
jdbc.properties
# Properties file with JDBC-related settings applied by PropertyPlaceholderConfigurer.
jdbc.url=jdbc:mysql://localhost/p_joo15_dev?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.username=root
jdbc.password=pw
弹簧主-DAO-的test.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<context:property-placeholder location="classpath*:META-INF/spring/*.properties"/>
<context:component-scan base-package="com.prosveta.backend">
<context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>
<!-- This will ensure that hibernate or jpa exceptions are automatically translated into
Spring's generic DataAccessException hierarchy -->
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<import resource="spring-datasource.xml"/>
<import resource="spring-jpa.xml"/>
<!-- required only for main method in ThoughtDaoImpl used to investigate
the delayed db creation problem -->
<bean id="thoughtDaoBean" class="com.prosveta.backend.daoimpl.thought.ThoughtDaoImpl" />
</beans>
现在是java代码
模型类
package com.prosveta.backend.model.thought;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.QueryHint;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import com.prosveta.backend.model.DomainObject;
import com.prosveta.backend.model.language.Language;
@SuppressWarnings("serial")
@Entity
@Table(name="jos_thoughts_p")
@NamedQueries({
@NamedQuery(name = "Thought.getThought",
query = "select thought from Thought thought where thought.date = :date and thought.language = :language",
hints={@QueryHint(name="org.hibernate.cacheable",value="true")}),
@NamedQuery(name = "Thought.getAllThoughtIdsBeforeDate",
query = "select thought.id from Thought thought where thought.date < :date and thought.language = :language",
hints={@QueryHint(name="org.hibernate.cacheable",value="true")}),
// it seems not a good idea to cache the query below since the 2 dates doublet has few chances to be used often in a short period of time !
@NamedQuery(name = "Thought.getAllThoughtIdsBeforeDateExceptExclusionDate",
query = "select thought.id from Thought thought where thought.date < :date and thought.language = :language and thought.date != :exclusionDate"),
})
public class Thought implements DomainObject {
private Integer id;
private Date date;
private String language;
private Integer treeOfLife;
private Integer twoNatures;
private String text;
private String keyword;
private String sentence;
public Thought() {
}
public Thought(Integer id, Date date, String language, Integer treeOfLife,
Integer twoNatures, String text, String keyword, String sentence) {
super();
this.id = id;
this.date = date;
this.language = language;
this.treeOfLife = treeOfLife;
this.twoNatures = twoNatures;
this.text = text;
this.keyword = keyword;
this.sentence = sentence;
}
@Id
@GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Temporal(TemporalType.DATE)
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
/**
* Returns the Language enum denoting the thought language
* @return
*/
@Transient
public Language getLanguageEnum() {
return Language.valueOf(language);
}
@Column(name = "tree_of_life", columnDefinition="SMALLINT")
public Integer getTreeOfLife() {
return treeOfLife;
}
public void setTreeOfLife(Integer treeOfLife) {
this.treeOfLife = treeOfLife;
}
@Column(name = "2_natures", columnDefinition="SMALLINT")
public Integer getTwoNatures() {
return twoNatures;
}
public void setTwoNatures(Integer twoNatures) {
this.twoNatures = twoNatures;
}
@Column(columnDefinition="LONGTEXT")
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getKeyword() {
return keyword;
}
public void setKeyword(String keyword) {
this.keyword = keyword;
}
public String getSentence() {
return sentence;
}
public void setSentence(String sentence) {
this.sentence = sentence;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Thought [id=" + id + ", date=" + date + ", language="
+ language + ", treeOfLife=" + treeOfLife + ", twoNatures="
+ twoNatures + ", text=" + text + ", keyword=" + keyword
+ ", sentence=" + sentence + "]";
}
}
通用dao基类
package com.prosveta.backend.daoimpl;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.dao.DataAccessException;
import com.prosveta.backend.dao.GenericDao;
import com.prosveta.backend.model.DomainObject;
/*
* This class contains a generic JPA implementation of
* the CRUD operations provided by dao's.
*/
@SuppressWarnings("unchecked")
public class GenericDaoImpl<T extends DomainObject> implements GenericDao<T> {
private Class<T> type;
@PersistenceContext
protected EntityManager entityManager;
public GenericDaoImpl(Class<T> type) {
super();
this.type = type;
}
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
public EntityManager getEntityManager() {
return this.entityManager;
}
public T get(Long id) {
return (T) this.entityManager.find(type, id);
}
public List<T> getAll() {
return this.entityManager.createQuery(
"select obj from " + type.getName() + " obj").getResultList();
}
public void save(T object) throws DataAccessException {
this.entityManager.persist(object);
}
public void delete(T object) throws DataAccessException {
this.entityManager.remove(object);
}
}
使用我用来跟踪持久性问题的主要方法的dao类
package com.prosveta.backend.daoimpl.thought;
import java.util.Date;
import java.util.List;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.prosveta.backend.dao.thought.ThoughtDao;
import com.prosveta.backend.daoimpl.GenericDaoImpl;
import com.prosveta.backend.model.language.Language;
import com.prosveta.backend.model.thought.Thought;
@Repository("thoughtDao")
public class ThoughtDaoImpl extends GenericDaoImpl<Thought> implements
ThoughtDao {
private static Log log = LogFactory.getLog(ThoughtDaoImpl.class);
private ThoughtDaoImpl() {
super(Thought.class);
}
/*
* (non-Javadoc)
*
* @see
* com.prosveta.backend.dao.thought.ThoughtDao#getThought(java.util.Date,
* com.prosveta.backend.model.language.Language)
*/
public Thought getThought(Date date, Language language) {
Query q = this.entityManager.createNamedQuery("Thought.getThought");
q.setParameter("date", date);
q.setParameter("language", language.toString());
Thought thought = null;
try {
thought = (Thought) q.getSingleResult();
} catch (NoResultException e) {
log.error("No thought found for date " + date + " and language "
+ language);
throw e;
}
log.debug("Thought retrieved from db: " + thought);
return thought;
}
/*
* (non-Javadoc)
*
* @see com.prosveta.backend.dao.thought.ThoughtDao#
* getAllThoughtIdsForThoughtBeforeDate(java.util.Date,
* com.prosveta.backend.model.language.Language)
*/
@SuppressWarnings("unchecked")
@Override
public List<Long> getAllThoughtIdsForThoughtBeforeDate(Date date,
Language language) {
Query q = this.entityManager
.createNamedQuery("Thought.getAllThoughtIdsBeforeDate");
q.setParameter("date", date);
q.setParameter("language", language.toString());
List<Long> ids = q.getResultList();
log.debug(ids.size()
+ " thought ids retrieved from db satisfying date < " + date
+ " for language " + language);
return ids;
}
/*
* (non-Javadoc)
*
* @see com.prosveta.backend.dao.thought.ThoughtDao#
* getAllThoughtIdsForThoughtBeforeDateExceptExclusionDate(java.util.Date,
* com.prosveta.backend.model.language.Language, java.util.Date)
*/
@SuppressWarnings("unchecked")
@Override
public List<Long> getAllThoughtIdsForThoughtBeforeDateExceptExclusionDate(
Date date, Language language, Date exclusionDate) {
Query q = this.entityManager
.createNamedQuery("Thought.getAllThoughtIdsBeforeDateExceptExclusionDate");
q.setParameter("date", date);
q.setParameter("language", language.toString());
q.setParameter("exclusionDate", exclusionDate);
List<Long> ids = q.getResultList();
log.debug(ids.size()
+ " thought ids retrieved from db satisfying date < " + date
+ " and != " + exclusionDate + " for language " + language);
return ids;
}
public static void main(String[] args) {
ThoughtDao thoughtDao = null;
try {
ApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "classpath:/META-INF/spring/spring-master-dao-test.xml" });
thoughtDao = (ThoughtDao) context.getBean("thoughtDaoBean");
} catch (Exception e) {
log.fatal(e);
throw new RuntimeException(e);
}
Thought thought = new Thought(null, new Date(),
"FR", new Integer(0), new Integer(0),
"Pensée 1", "", "");
saveThought(thoughtDao, thought);
}
/**
* @param thoughtDao
* @param t1
*/
@Transactional(readOnly=false, propagation=Propagation.REQUIRES_NEW)
private static void saveThought(ThoughtDao thoughtDao, Thought t1) {
thoughtDao.save(t1);
}
}
非常感谢您的帮助,感谢您的阅读!
让 - 皮埃尔
答案 0 :(得分:6)
Spring可以将方法包装到事务中,如果它是已实例化的bean的实例方法。您将@Transactional
注释放在从main方法直接调用的静态方法上。 Spring无法将此调用包装到事务中。将注释放在save方法上,它应该更好。