Newbie question about mapping and persisting in Hibernate,JBoss Seam
ronaldosv Jan 16, 2010 3:02 PMHello everybody. Sorry for the post so long, but I could not be shorter and sorry if this post in the wrong place, but I do not know if the problem is the mapping or is it something I'm doing wrong when I try to persist the object ... .
I have a problem to persist an object in a relation @ OneToMany. Here is the picture.
It is a module polls, where I am developing a piece of voting, involving 3 entities; Polls, Pollsoptions and Pollsvotes basically have to do the following when the User votes on a poll:
In Poll entity, update the number of votes adding 1 and update the last date of voting.
In PollsOptions entity, I have to update the number of votes received for the option that the user choose, by adding the option 1
Finally, add a record in the entity PollsVotes.
Well, I'm using JBoss Seam and did the reverse engineering of entities using JBoss Tools, and I'm using classes that JBoss Tolls generates the entities and sessions beans, I did not see anything wrong with the mapping of entities, but the problem I have is when I try to insert a record in the entity PollsOptios, the updates that I do in the other entities work without any problem.
Here's how the classes are mapped ...
@Entity @Table(name = "polls", catalog = "polls") public class Polls implements java.io.Serializable { private List<Pollsvotes> pollsvoteses = new ArrayList(); private List<Pollsoptions> pollsoptionses = new ArrayList(); @OneToMany(fetch = FetchType.LAZY, mappedBy = "polls") public List<Pollsvotes> getPollsvoteses() { return this.pollsvoteses; } public void setPollsvoteses(List<Pollsvotes> pollsvoteses) { this.pollsvoteses = pollsvoteses; } @OneToMany(fetch = FetchType.LAZY, mappedBy = "polls") public List<Pollsoptions> getPollsoptionses() { return this.pollsoptionses; } public void setPollsoptionses(List<Pollsoptions> pollsoptionses) { this.pollsoptionses = pollsoptionses; } } @Entity @Table(name = "pollsoptions", catalog = "polls") public class Pollsoptions implements java.io.Serializable { private PollsoptionsId id; private Polls polls; private int pollsoptTotalvotes; private List<Pollsvotes> pollsvoteses = new ArrayList<Pollsvotes>(0); @EmbeddedId @AttributeOverrides( { @AttributeOverride(name = "pollId", column = @Column(name = "poll_id", nullable = false)), @AttributeOverride(name = "pollsoptId", column = @Column(name = "pollsopt_id", nullable = false)) }) @NotNull public PollsoptionsId getId() { return this.id; } public void setId(PollsoptionsId id) { this.id = id; } @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "poll_id", nullable = false, insertable = false, updatable = false) @NotNull public Polls getPolls() { return this.polls; } public void setPolls(Polls polls) { this.polls = polls; } @Column(name = "pollsopt_totalvotes", nullable = false) public int getPollsoptTotalvotes() { return this.pollsoptTotalvotes; } public void setPollsoptTotalvotes(int pollsoptTotalvotes) { this.pollsoptTotalvotes = pollsoptTotalvotes; } @OneToMany(fetch = FetchType.LAZY, mappedBy = "pollsoptions") public List<Pollsvotes> getPollsvoteses() { return this.pollsvoteses; } public void setPollsvoteses(List<Pollsvotes> pollsvoteses) { this.pollsvoteses = pollsvoteses; } } @Entity @Table(name = "pollsvotes", catalog = "polls") public class Pollsvotes implements java.io.Serializable { private PollsvotesId id; private Users users; private Pollsoptions pollsoptions; private Polls polls; private Date pollsvoteDate; public Pollsvotes() { } public Pollsvotes(PollsvotesId id, Users users, Pollsoptions pollsoptions, Polls polls, Date pollsvoteDate) { this.id = id; this.users = users; this.pollsoptions = pollsoptions; this.polls = polls; this.pollsvoteDate = pollsvoteDate; } @EmbeddedId @AttributeOverrides( { @AttributeOverride(name = "usrId", column = @Column(name = "usr_id", nullable = false)), @AttributeOverride(name = "pollId", column = @Column(name = "poll_id", nullable = false)) }) @NotNull public PollsvotesId getId() { return this.id; } public void setId(PollsvotesId id) { this.id = id; } @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "usr_id", nullable = false, insertable = false, updatable = false) @NotNull public Users getUsers() { return this.users; } public void setUsers(Users users) { this.users = users; } @ManyToOne(fetch = FetchType.LAZY) @JoinColumns( { @JoinColumn(name = "poll_id", referencedColumnName = "poll_id", nullable = false, insertable = false, updatable = false), @JoinColumn(name = "pollsopt_id", referencedColumnName = "pollsopt_id", nullable = false, insertable = false, updatable = false) }) @NotNull public Pollsoptions getPollsoptions() { return this.pollsoptions; } public void setPollsoptions(Pollsoptions pollsoptions) { this.pollsoptions = pollsoptions; } @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "poll_id", nullable = false, insertable = false, updatable = false) @NotNull public Polls getPolls() { return this.polls; } public void setPolls(Polls polls) { this.polls = polls; } @Temporal(TemporalType.TIMESTAMP) @Column(name = "pollsvote_date", nullable = false, length = 23) @NotNull public Date getPollsvoteDate() { return this.pollsvoteDate; } public void setPollsvoteDate(Date pollsvoteDate) { this.pollsvoteDate = pollsvoteDate; } }
Here is the method Vote I wrote to perform the vote, without control of transaction yet, only the first steps ... and really do not know if this is correct nd best way to do this, before to try this approach, I tried add the PollsVotes entity in the attribute pollsvoteses of the entity Polls and persist, but nothing happened, so I decided to try this approach and I am getting the following error:
insert into polls.dbo.pollsvotes (pollsvotedate, pollid, usrid) values (?, ?, ?)
17:37:24,782 WARN JDBCExceptionReporter SQL Error: 515, SQLState: 23000
17:37:24,782 ERROR JDBCExceptionReporter Cannot insert the value NULL into column 'pollsoptid', table 'polls.dbo.pollsvotes'; column does not allow nulls. INSERT fails.
17:37:24,783 ERROR AbstractFlushingEventListener Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: could not insert: org.domain.pollsweb.entity.Pollsvotes
The correct SQL statment would be :
insert into polls.dbo.pollsvotes (pollsvotedate, pollid, usrid,pollsoptid) values (?, ?, ?, ?)
Basically he is ignoring the pv.setPollsoptions (po), which is listed in the code below.
@Name("pollsHome") public class PollsHome extends EntityHome<Polls> { @In(create = true) CategoriesHome categoriesHome; @In(create = true) UsersHome usersHome; public void vote(int optionVotedId){ Iterator<Pollsoptions> it = getPollsoptionses().iterator(); boolean foundVotedOpt = false; Pollsoptions po = null; // TODO - find a best way to do this while (it.hasNext() && !foundVotedOpt ){ po = it.next(); if (po.getId().getPollsoptId() == optionVotedId) { foundVotedOpt = true; } } po.setPollsoptTotalvotes(po.getPollsoptTotalvotes()+1); getInstance().setPollTotalvotes(getInstance().getPollTotalvotes()+1); getInstance().setPollLastvotedate(new java.util.Date()); PollsvotesId id = new PollsvotesId(getInstance().getUsers().getUsrId(), getInstance().getPollId()); Pollsvotes pv = new PollsvotesHome().getInstance(); pv.setId(id); pv.setPolls(getInstance()); pv.setPollsoptions(po); pv.setPollsvoteDate(new java.util.Date()); pv.setUsers(getInstance().getUsers()); PollsvotesHome pvHome = new PollsvotesHome(); pvHome.setInstance(pv); persist(); pvHome.persist(); } }
Someone please tell me where I am wrong??
Grateful
Ronaldo.