1
welsmann 2014-11-07 21:33:03 +08:00 1
根据需要加入@GeneratedValue注解
|
2
qping 2014-11-07 22:29:59 +08:00 1
下面是百度搜的,印象中是这样的。
"session在什么情况下执行flush:默认在事务提交时;显示的调用flush;在执行查询前,如:iterate. 调用save后,只是将对象纳入到了session的管理,不会发出insert语句,如没有主键会根据主键生成策略生成主键,把脱管或瞬态对象变为持久态对象." http://zhidao.baidu.com/link?url=p8o00ykbezRThHvydBXl3RvUZFO1cvOTB-XcD3m5I2K1idgOcSdTAP2GAC-xEaJOCe01G5S7mOSfMpzzvH5m-K |
3
shuson 2014-11-08 10:10:40 +08:00 1
@GeneratedValue(strategy = GenerationType.AUTO) cannot be used with String type. A straightforward solution could be to use the @PrePersist annotation on your entity class.
|
4
forreal OP @welsmann 主键我想自己指定,不想自动生成。但是我试了如果实体的主键是Long类型却不加@GeneratedValue 也会save()时不插入数据库。
@qping 如果不加@GeneratedValue到主键上,commit()时就不会插入数据库。不知道为什么。(哪怕我手动指定了主键) @shuson 意思是先用自动生成主键,然后再@PrePersist注解的方法 改对象的主键吗? |
5
qping 2014-11-08 19:23:44 +08:00
有其他语句吗 比如update语句,没有错误日志,相关配置,只能等高手过来帮你猜了 - -
|
6
qping 2014-11-08 19:29:41 +08:00
我始终不认为你错的地方在于注解GeneratedValue 或者 主键Long类型。
事务提交后没有insert语句,应该是事务配置或者hibernate对象状态。 http://www.baidu.com/s?wd=hibernate%E5%AF%B9%E8%B1%A1%E7%8A%B6%E6%80%81 http://www.baidu.com/s?wd=hibernate%20%E4%B8%BB%E9%94%AE%E7%94%9F%E6%88%90 我曾经因为spring mvc传递的是 持久态的对象,修改其主键后怎么改后台都是update,而我想要的是insert ,楼主看是不是这种情况 |
7
forreal OP @qping 没有错误日志(控制台上sql语句,错误日志什么都没有),
配置都是照https://github.com/ZhibingXie/SpringMVC-Spring-Hibernate来配的。 就是有一个实体类,id用的是名字(String类型),而且没有注解@GeneratedValue,然后事务提交不发出insert语句也不存入数据库。必须手动调用flush()才行。 但是如果在那个实体类上额外加上一个int或long的id,并且注解@GeneratedValue(我感觉是问题的关键),配置什么的都不用改就可以不手动调用flush(),而是事务提交时就自动发出insert语句并插入数据库了。 |
9
qping 2014-11-08 20:03:51 +08:00
你的代码呢
|
10
forreal OP @qping
model层: @Entity public class Node { private String name; @Id public String getName() { return name; } public void setName(String name) { this.name = name; } } dao层: baseDaoImpl.java: public class BaseDaoImpl { private SessionFactory sessionFactory; public SessionFactory getSessionFactory() { return sessionFactory; } @Resource(name = "sessionFactory") public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public Session getCurrentSession(){ return sessionFactory.getCurrentSession(); } } NodeDaoImpl.java: @Repository public class NodeDaoImpl extends BaseDaoImpl implements NodeDao { @Override public Serializable save(Node node){ Session session = getCurrentSession(); session.setFlushMode(FlushMode.COMMIT); Serializable id = session.save(node); //session.flush(); return id; } } service层: @Service public class NodeServiceImpl implements NodeService { @Override public Node add(Node node) { int id = (Integer)nodeDao.save(node); return node; } @Resource public void setNodeDao(NodeDao nodeDao) { this.nodeDao = nodeDao; } private NodeDao nodeDao; } controller层(spring mvc): @Controller @RequestMapping("/admin") public class AdminController { @RequestMapping public String index(){ return "admin/admin"; } @RequestMapping(value = "/node") public String addNode(@RequestParam("name")String nodename,ModelMap model){ Node node = new Node(); node.setName(nodename); nodeService.add(node); model.addAttribute("msg","添加成功"); return "admin/admin"; } @Resource public void setNodeService(NodeService nodeService) { this.nodeService = nodeService; } private NodeService nodeService; } spring-hibernate.xml配置文件: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 数据库连接配置 --> <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${driveClassName}" /> <property name="url" value="${jdbc_url}" /> <property name="username" value="${jdbc_name}" /> <property name="password" value="${jdbc_password}" /> <property name="initialSize" value="5" /> <property name="maxConnLifetimeMillis" value="60000" /> <property name="maxTotal" value="20" /> <property name="maxIdle" value="5" /> </bean> <!-- Hibernate属性配置 --> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="hibernateProperties"> <props> <prop key="hibernate.hbm2ddl.auto">update</prop> <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">true</prop> </props> </property> <property name="packagesToScan"> <list> <value>model</value> </list> </property> </bean> <!-- 事务配置 --> <!-- 需要引入tx的命名空间 --> <!-- 这是事务通知操作,使用的事务管理器引用自 transactionManager --> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!-- 指定哪些方法需要加入事务,这里懒惰一下全部加入,可以使用通配符来只加入需要的方法 --> <tx:attributes> <tx:method name="save*" propagation="REQUIRED" /> <tx:method name="add*" propagation="REQUIRED" /> <tx:method name="edit*" propagation="REQUIRED" /> <tx:method name="delete*" propagation="REQUIRED" /> <tx:method name="get*" propagation="REQUIRED" read-only="true"/> <tx:method name="is*" propagation="REQUIRED" read-only="true"/> <tx:method name="follow*" propagation="REQUIRED" /> <!--<tx:method name="*" propagation="REQUIRED" />--> </tx:attributes> </tx:advice> <!-- 需要引入aop的命名空间 --> <aop:config proxy-target-class="true"> <!-- 切入点指明了在执行Service的所有方法时产生事务拦截操作 --> <aop:pointcut id="transactionPointcut" expression="execution(* service.Impl.*.*(..))" /> <!-- 定义了将采用何种拦截操作,这里引用到 txAdvice --> <aop:advisor pointcut-ref="transactionPointcut" advice-ref="txAdvice" /> </aop:config> </beans> |
11
qping 2014-11-10 09:03:05 +08:00
没看出哪有问题
<tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="*" rollback-for="Exception"/> </tx:attributes> </tx:advice> 改成这样试试 |
12
qping 2014-11-10 09:06:38 +08:00 1
或者在service类上加 @Transactional 标签
@Service @Transactional public class NodeServiceImpl implements NodeService { @Override public Node add(Node node) { int id = (Integer)nodeDao.save(node); return node; } |
13
forreal OP @qping
xml加rollback-for="Exception" 和利用@Transactional都分别试过了,还是不行。 还是需要显式调用flush()或者给实体加一个额外的id数字字段并且@GeneratedValue才可以插入数据库 |