spring+hibernate(一对多)向数据库添加数据

有两个问题:
[b][color=red][size=large]1、spring和hibernate中的一对多问题(包括添加、删除和更行)~我现在这么写代码规范吗?

2、总感觉项目里加了spring之后,处理事务的速度变得慢了很多~比只是加入hibernate的时候慢~这是神马原因呢?[/size][/color][/b]
数据库有两个表:“user”和“order”;一个“user”对应多个“order”;user表的外键关联在“order”表中

具体的Dao借口都继承了泛型的Dao(泛型Dao里面有spring的数据操作)

现在我想在“order”里面添加数据~测试结果现在添加失败~但没有Exception;以下是我的代码,问题应该就在[color=red][size=large]“OrderServiceImpl”[/size][/color]中;

(Spring:ApplicationContext.xml)

[code="java"] 1. <!-- -->



  1. <!-- -->

  2. <!-- -->





    1. <!-- -->

    2. <!-- -->










    3. <!-- -->

    4. <!-- -->

















    5. <!-- --> [/code]

User.hbm.xml

[code="java"] 1.














  1. [/code]

Order.hbm.xml

[code="java"] 1.

















  1. [/code]

OrderDaoImpl(向数据库底层添加数据)
[code="java"]
public class OrderDaoImpl extends GenericHibernateDaoImpl implements OrderDao {

boolean success =false;

public boolean addOrder(Order order) {

    success=saveObj(order);
    System.out.println("save order");
    return success;
}

[/code]

[b][color=red]OrderServiceImpl(这层和用户沟通~问题出现在这代码当中:第16~19行)[/color][/b]

[code="java"] 1. public boolean addOrder(String orderName, Integer orderStatue,

  1. String userName,Integer version) {
  2. ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
  3. Order order = (Order)ctx.getBean("Order");
  4. userService = (UserService) ctx.getBean("UserService");
  5. orderDao=(OrderDao)ctx.getBean("OrderDao");

  6. boolean success = false;

    1. Integer userId = userService.findUserId(userName);//get a UserID by userName
    2. User user = userService.findUser(userId);//get an User by UserID

    3. order.setOrderName(orderName);
    4. order.setOrderStatue(orderStatue);
    5. order.setVersion(version);
    6. order.setUser(user);//set an "user" into the order;

    7. try {
    8. success=orderDao.addOrder(order);//保存“order”结果提示返回的“success”值为“false”,应该怎么办好呢?
    9. } catch (Exception e) {
    10. success = false;
    11. e.printStackTrace();
    12. }

    13. return success;
    14. } [/code]

如果单单用sql语句是可以插入的~但是我想用hibernate的特性把参数值set进去~thanks

[quote]现在经你提点,一对多添加数据确实成功了~然而有新问题出现~我原来的思路是先查找出一个User~然后再根据这个User来添加他的Order~应该只是在Order表里面新增数据才合理~但是按照我写的程序~问题是:User表里同样会新增一个同名的User(只是ID不同)~新插入的Order所关联的User也是新增的那个同名User~这样的结果是不合符程序设计的原意~出现此问题的原因是:在执行完泛型Dao的Save()方法后 session被关闭了~难道又要想hibernate那样把所有事物都放在BeginTransaction()和commit()当中完成吗?这样做会出现很多重复的代码~不符合设计的原则吧~希望你能够指点一下~
[/quote]

这一整个应该在一个事务中啊,在这个事务提交之前,session不会关闭。
[code="java"]
User user = userService.findUser(userId);//get an User by UserID

order.setUser(user);

user.addOrcer(order);

updateUser(user); // 这应该是update
[/code]

数据库中有没有那条记录了?

GenericHibernateDaoImpl中的saveObj贴出来看看。

[code="java"]
public boolean saveObj(T entity) {

try {

getHibernateTemplate().save(entity);

success = true;

} catch (HibernateException he) {

he.printStackTrace();

success = false;

throw he; // 出错时抛出异常,能返回false吗?
}

return success; // 这是一个类变量?多线程时,返回的是什么谁也不知道。
} [/code]

把异常贴出来看看,如何有的话。

[code="xml"]



[/code]

Spring中Bean默认是单例对象,如果你这样写,那么相当于:
Users user = new Users();
Order order = new Order();

然后到无论到哪里要创建、或使用User或Oorder对象,你就直接拿上面的user和order,这样肯定有问题

应该把这两行bean删除,在用到的地方new一个对象

[quote]就是连异常都没有输出[/quote]

没有提交到数据库,可能是事务的问题。在orderDao.addOrder(order);之前先保存另外一个表的数据试试能不能成功。

[code="java"]
User user = userService.findUser(userId);//get an User by UserID

order.setUser(user);
user.addOrcer(order);
saveUser(user); // 调dao保存
// saveOrder(order); // 这句应该可写、可不写。
[/code]

整个配置文件都没有看到spring的事务配置,你的配置了。贴出来看看

你现在是一对多,那么操作是由一来完成对吧?
一般的将”一”这一端设置为inverse=”false”,cascade=”all” ,这样一般的操作只需要在”一”这一端操作,此适合于标志性一对多的情况
而Inverse=”true”的表示两个实体的关系由对方去维护。

[code="java"]
public boolean saveObj(T entity) {

try {

getHibernateTemplate().save(entity);

success = true;

} catch (HibernateException he) {

he.printStackTrace();

success = false;

throw he;

}

return success;

}

[/code]
这里是不是有问题?

抛出的异常是:org.springframework.dao.DataAccessException

应该是用以下某一个来捕捉才对,而不是HibernateException吧
org.springframework.dao.DataAccessException
RuntimeException
Exception

你调试一下,应该没进入这一段:
[code="java"]
catch (HibernateException he) {

he.printStackTrace();

success = false;

throw he;

}
[/code]

[quote]但是在userService.findUser(userId)里面我继承了spring的getHibernateTemplate的方法~这方法运行完之后不是会执行一个session.close()吗?因此我再执行一个saveUser()之后不就会重新调用getHibernateTemplate.save()的方法再开一个session吗?[/quote]

hibernateTemplate里用的session,如果是在事务中的,不会新开一次,而是直接用事务那个,在完成后也不会关闭session,而是留给事务来关。

[quote]1、现在我这么写代码规范吗?
2、为什么加入spring总感觉那个速度好像慢了很多的?[/quote]

  1. 你这样写确实有问题,如: [code="java"] public boolean addOrder(String orderName, Integer orderStatue, String userName,Integer version) {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
    Order order = (Order)ctx.getBean("Order");
    userService = (UserService) ctx.getBean("UserService");
    orderDao=(OrderDao)ctx.getBean("OrderDao");
    [/code] 这应该用注入,而不是在方法里获取。

建议看看 [url="http://www.springside.org.cn/"]springside[/url]是怎么写的。

  1. 用Spring不会让你的应用慢下来。可能是事务的问题吧,把不需要事务的方法,不要用事务或者设置事务为readonly。