hibernate问题

jjzhyan8645 2009-09-30 10:53:06
class A{ id ; List<b> } class B{id };

Table A |id | Table B | id , Aid|


问save(B) 时能把a保存到数据库么 ? 用hibernate Jpa 怎么写
...全文
113 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
woming66 2009-09-30
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 longtenggdf 的回复:]
我是说你代码有问题,我项目中也想这样用,但是没有成功~
user中对应的多对一到departmentInfo
Java code
@ManyToOne(cascade= { CascadeType.PERSIST, CascadeType.MERGE })
@JoinColumn(name="DEPARTMENT_ID")public DepartmentInfo getDepartmentInfo() {return departmentInfo;
}publicvoid setDepartmentInfo(DepartmentInfo departmentInfo) {this.departmentInfo= departmentInfo;
}
然后我在新增user的时候,new了一个departmentInfo.user set进去,然后再save(user).就包user.departmentId不能为空。数据库中user的departmentId是not null.
我在想级联保存的顺序是否是这样,先保存user对象,再保存departmentInfo对象,然后在将departmentInfo的Id赋给user?如果真是这样,那这里就不能用级联保存了!
[/Quote]

你错了 你new了一个user 之后放入了departmentInfo.users set的集合中,请问jpa默认的一对多关系维护端在哪头?是多的一端而不是一的一段,而此时你save了user 因为user一端是关系的维护端,那么你user的departmentInfo属性是空的 保存的时候又因为你departmentInfo字段设置了非空约束,很显然回报底层的Exception
正确的写法是 先load一个departmentInfo(如果数据库中没有是就new一个,这也是为什么设置了级联保存原因),因为你没有系部怎么会有系部下的用户,在new 一个user之后将user的departmentInfo属性设置为刚才load出来的departmentInfo,最后再save user
longtenggdf 2009-09-30
  • 打赏
  • 举报
回复
是说。。。。少了个字
longtenggdf 2009-09-30
  • 打赏
  • 举报
回复
我是说你代码有问题,我项目中也想这样用,但是没有成功~
user中对应的多对一到departmentInfo

@ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
@JoinColumn(name = "DEPARTMENT_ID")
public DepartmentInfo getDepartmentInfo() {
return departmentInfo;
}

public void setDepartmentInfo(DepartmentInfo departmentInfo) {
this.departmentInfo = departmentInfo;
}

然后我在新增user的时候,new了一个departmentInfo.user set进去,然后再save(user).就包user.departmentId不能为空。数据库中user的departmentId是not null.
我在想级联保存的顺序是否是这样,先保存user对象,再保存departmentInfo对象,然后在将departmentInfo的Id赋给user?如果真是这样,那这里就不能用级联保存了!
woming66 2009-09-30
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 longtenggdf 的回复:]
引用 2 楼 woming66 的回复:
你说的方法是不行的!

public class B {
  @Id
  @GeneratedValue
  private int id;

  @ManyToOne(cascade={CascadeType.PERSIST})
  private A a;
}
设置一个级联保存就可以了

我这样设的 不行哦!!
[/Quote]

哪个地方不行哦, 指出来, 这些代码都是手写的 有的地方都省略没写!
longtenggdf 2009-09-30
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 woming66 的回复:]
你说的方法是不行的!

public class B {
  @Id
  @GeneratedValue
  private int id;

  @ManyToOne(cascade={CascadeType.PERSIST})
  private A a;
}
设置一个级联保存就可以了
[/Quote]
我这样设的 不行哦!!
woming66 2009-09-30
  • 打赏
  • 举报
回复
你说的方法是不行的!

public class B {
@Id
@GeneratedValue
private int id;

@ManyToOne(cascade={CascadeType.PERSIST})
private A a;
}
设置一个级联保存就可以了
caili314 2009-09-30
  • 打赏
  • 举报
回复
不能. 反过来,如果A->B有@OneToMany的话, 则可以.
shichao2008 2009-09-30
  • 打赏
  • 举报
回复
学习
woming66 2009-09-30
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 longtenggdf 的回复:]
bookService.saveBook(book, "java se");
这句是什么意思呢?
我在网上看好像也有个什么深度级联和广度级联。我用的是hibernateDao自带的save方法。跟你这个
em.persist(book);有区别么?难道这就是传说中的深度级联----从根部往上级联?
忘了说我用的是springside框架,dao类封装我没关联源码,什么时候用空我去看下,反正我这里是不行。它save的时候会老老实实先去insert book.然后typeId就报非空。
跟你讨论学习了很多,感谢
[/Quote]

我也没遇见过你这种情况 挺奇怪的 实在不行就别用级联了 级联也不是什么太好的东西!就是少写点代码 呵呵 这个聊的太麻烦了 我QQ86594187!
woming66 2009-09-30
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 longtenggdf 的回复:]
bookService.saveBook(book, "java se");
这句是什么意思呢?
我在网上看好像也有个什么深度级联和广度级联。我用的是hibernateDao自带的save方法。跟你这个
em.persist(book);有区别么?难道这就是传说中的深度级联----从根部往上级联?
忘了说我用的是springside框架,dao类封装我没关联源码,什么时候用空我去看下,反正我这里是不行。它save的时候会老老实实先去insert book.然后typeId就报非空。
跟你讨论学习了很多,感谢
[/Quote]

呵呵 客气了 都是搞技术的 对待问题就应该追根究底

Book book = new Book();
book.setName("java core");

bookService.saveBook(book, "java se");

public void saveBook(Book book, String typeName) {

BookType type = new BookType();
type.setName(typeName);

book.setType(type);

em.persist(book); //就是调用底层的session.save方法,我也不清楚里面的级联算法是哪种(深度级联和广度级联),已经测试通过 能实现级联操作 一点问题都没有!
}

@PersistenceContext
private EntityManager em;
我面向的是JPA接口
底层实现是HIBERNATE
深度级联和广度级联分别对应不同的算法一个是用到了递归,一个用到了queue
我没用hibernateDao自带的getHibernateTemplate.save(),因为我不喜欢直接继承hibernateDao,而是直接将一个sessionFactory注入到dao接口的实现类里

我估计这个跟getHibernateTemplate.save(),没什么关系 还是哪块配置写的有问题
longtenggdf 2009-09-30
  • 打赏
  • 举报
回复
bookService.saveBook(book, "java se");
这句是什么意思呢?
我在网上看好像也有个什么深度级联和广度级联。我用的是hibernateDao自带的save方法。跟你这个
em.persist(book);有区别么?难道这就是传说中的深度级联----从根部往上级联?
忘了说我用的是springside框架,dao类封装我没关联源码,什么时候用空我去看下,反正我这里是不行。它save的时候会老老实实先去insert book.然后typeId就报非空。
跟你讨论学习了很多,感谢
woming66 2009-09-30
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 longtenggdf 的回复:]
晕~~我明白的。说了半天,你是没明白我的意思。
一句话,我想说,多对一外键非空不能级联保存!完毕!
[/Quote]

客气了 你也没明白我的意思 多对一外键非空能级联保存 我已经实现了

Book book = new Book();
book.setName("java core");

bookService.saveBook(book, "java se");

BookType type = new BookType(); //数据库中没有这条记录的 我是new出来的
type.setName(typeName);

book.setType(type);
em.persist(book); //保存的时候会先保存BookType 最后再保存book
longtenggdf 2009-09-30
  • 打赏
  • 举报
回复
不过还是谢谢你 果然是热心的小强!
longtenggdf 2009-09-30
  • 打赏
  • 举报
回复
晕~~我明白的。说了半天,你是没明白我的意思。
一句话,我想说,多对一外键非空不能级联保存!完毕!
woming66 2009-09-30
  • 打赏
  • 举报
回复
改一下@JoinColumn(name="typeId", nullable=false)
woming66 2009-09-30
  • 打赏
  • 举报
回复
我做了一个小demo你自己看看吧!完全是按照你的思想编写的(单项多对一)!你要再不明白我也没办法了!
@Entity
@Table(name="t_book")
public class Book {

@Id
@GeneratedValue
private int id;

@Column(length=50)
private String name;

@ManyToOne(cascade={CascadeType.PERSIST})
@JoinColumn(name="typeId", nullable=true)
private BookType type;

public BookType getType() {
return type;
}

public void setType(BookType type) {
this.type = type;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

@Entity
@Table(name="t_booktype")
public class BookType {

@Id
@GeneratedValue
private int id;

@Column(length=50)
private String name;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

public interface BookService {

public void saveBook(Book book, String typeName);
}

@TransactionAttribute
public class BookServiceImpl implements BookService {

@PersistenceContext
private EntityManager em;

public void saveBook(Book book, String typeName) {

BookType type = new BookType();
type.setName(typeName);

book.setType(type);

em.persist(book);
}

}

public class BookServiceImplTest {

private static BookService bookService;

@BeforeClass
public static void setUpBeforeClass() throws Exception {
try {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
bookService =(BookService) context.getBean("bookService");
} catch (RuntimeException e) {
e.printStackTrace();
}
}

@Test
public void test() {

Book book = new Book();
book.setName("java core");

bookService.saveBook(book, "java se");

}

}
longtenggdf 2009-09-30
  • 打赏
  • 举报
回复
另外。你说的
先load一个departmentInfo(如果数据库中没有是就new一个,这也是为什么设置了级联保存原因)

这句我没有明白,这里怎么就体现了级联保存么?先load一个或是new一个然后将它持久化,这里有级联么???!
longtenggdf 2009-09-30
  • 打赏
  • 举报
回复
关系的维护肯定是在多这一头。而且我是单向的多对一。
而楼主的问题也应该是这样。保存用户的时候是否能将部门也一并保存,结果是不能。其实我想说的和你说的差不多,多对一的时候,级联保存基本上是不能用的。除非外键可空(这里还须验证)。一对多的时候应该就没有问题(主控默认)。

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧