Olá pessoal. Desculpem o post tão longo, mas creio que não poderia ser mais curto …
Estou com um problema para persistir um objeto em uma relação @OneToMany. Eis o quadro.
É um módulo de enquetes, onde estou desenvolvendo a parte de votação, que envolve 3 entidades; Polls, Pollsoptions e Pollsvotes, basicamente tenho que fazer o seguinte quando o usuário vota em uma poll :
Na enteidade Poll, atualizar a quantidade de votos agregando +1 e atualizar a ultima data de votação.
Na enteidade PollsOptions, eu tenho que atualizar a quantidade de votos que aquela opção recebeu adicionano +1
E por fim, adicionar um registro na entidade PollsVotes.
Muito bem, eu estou usando o Jboss Seam e fiz a engenharia reversa das entidades, e estou utilizando as classes que ele gera, os entities e os sessions, não vi nada de errado no mapeamento dos entities, mas o problema que eu tenho é quando vou tentar inserir um registro na PollsOptios, pois os updates funcionam sem nenhum problema.
Eis como as classes estão mapeadas …
@Entity
@Table(name = "polls", catalog = "polls")
public class Polls implements java.io.Serializable {
// os demais atributos foram suprimidos ....
private int pollId;
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;
}
// os demais metodos foram suprimidos
}
@Entity
@Table(name = "pollsoptions", catalog = "polls")
public class Pollsoptions implements java.io.Serializable {
// os demais atributos foram suprimidos ....
private PollsoptionsId id;
private Polls polls;
private int pollsoptTotalvotes;
private List<Pollsvotes> pollsvoteses = new ArrayList<Pollsvotes>(0);
@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;
}
@OneToMany(fetch = FetchType.LAZY, mappedBy = "pollsoptions")
public List<Pollsvotes> getPollsvoteses() {
return this.pollsvoteses;
}
public void setPollsvoteses(List<Pollsvotes> pollsvoteses) {
this.pollsvoteses = pollsvoteses;
}
// os demais metodos foram suprimidos
}
@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;
}
}
Aqui está o metodo Vote que eu escrevi para fazer a votação, ta sem controle de transacao, são apenas os primeiros passos … Ta bem pog ainda, e na verdade não sei se essa é maneira correta de fazer, eu havia tentado simplesmente adicionar o entity do PollsVotes no atributo pollsvoteses da entidade Polls, mas ao persistir, nada acontecia, então resolvi tentar essa abordagem e estou obtendo o seguinte erro :
insert
into
polls.dbo.pollsvotes
(pollsvote_date, poll_id, usr_id)
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 ‘pollsopt_id’, 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]
Basicamente ele está ignorando o pv.setPollsoptions(po); que está listado no código abaixo.
@Name("pollsHome")
public class PollsHome extends EntityHome<Polls> {
@In(create = true)
CategoriesHome categoriesHome;
@In(create = true)
UsersHome usersHome;
public void vote(int optionVotedId){
System.out.println("########################" + optionVotedId + "#########################");
Iterator<Pollsoptions> it = getPollsoptionses().iterator();
boolean foundVotedOpt = false;
Pollsoptions po = null;
// TODO - ver como trazer a opcao escolhida sem ter que procurar na List
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();
}
}
Alguem poderia me dizer onde estou errando ???
Grato,
Ronaldo.