Salvar em cascata com Hibernate

Pessoal tenho as seguintes tabelas no banco de dados
tabela OCORRENCIA

CREATE TABLE `ocorrencia` (
  `oco_numero` bigint(20) NOT NULL auto_increment,
  `oco_data` datetime NOT NULL,
  `oco_abertopor` varchar(20) NOT NULL,
  `oco_obs_abertura` varchar(255) default NULL,
  `oco_dtconclusao` datetime default NULL,
  `oco_concluinte` varchar(20) default NULL,
  `oco_obs_conclusao` varchar(255) default NULL,
  `oco_cliente` bigint(20) NOT NULL,
  `oco_tp_ocorrencia` bigint(20) NOT NULL,
  `oco_distribuidor` bigint(20) NOT NULL,
  PRIMARY KEY  (`oco_numero`),
  KEY `FK1A94EBD7ACA08043` (`oco_distribuidor`),
  KEY `FK1A94EBD7C0B6CEAD` (`oco_cliente`),
  KEY `FK1A94EBD77D0B56C4` (`oco_tp_ocorrencia`),
  CONSTRAINT `FK1A94EBD77D0B56C4` FOREIGN KEY (`oco_tp_ocorrencia`) REFERENCES `tipoocorrencia` (`tp_oco_codigo`),
  CONSTRAINT `FK1A94EBD7ACA08043` FOREIGN KEY (`oco_distribuidor`) REFERENCES `distribuidor` (`dis_codigo`),
  CONSTRAINT `FK1A94EBD7C0B6CEAD` FOREIGN KEY (`oco_cliente`) REFERENCES `cliente` (`cli_codigo`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Tabela HST_OCORRENCIA

CREATE TABLE `hst_ocorrencia` (
  `hst_oco_data` date NOT NULL,
  `hst_oco_abertopor` varchar(20) default NULL,
  `hst_oco_obs` varchar(255) default NULL,
  `hst_oco_numero` bigint(20) NOT NULL,
  PRIMARY KEY  (`hst_oco_numero`,`hst_oco_data`),
  KEY `FK832ED12DC1A99B0` (`hst_oco_numero`),
  CONSTRAINT `FK832ED12DC1A99B0` FOREIGN KEY (`hst_oco_numero`) REFERENCES `ocorrencia` (`oco_numero`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

verifiquem que a tabela hst_ocorrencia tem a chave primaria composta por 2 campos e sendo 1 deles o numero da ocorrencia, ate ai tudo bem agora olhem as classes

Classe Ocorrencia

package br.com.europa.modelo;

import java.util.Date;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;

@Entity
public class Ocorrencia {
	
	/*
	 * membros
	 */
	
	@Id @GeneratedValue
	private Long oco_numero;
	
	@Column(nullable=false)
	private Date oco_data;
	
	@Column(length=20, nullable=false)
	private String oco_abertopor;
	
	@ManyToOne
	@JoinColumn(name="oco_cliente", nullable=false)
	private Cliente cliente;
	
	@ManyToOne
	@JoinColumn(name="oco_tp_ocorrencia", nullable=false)
	private TipoOcorrencia tipoOcorrencia;
	
	@ManyToOne
	@JoinColumn(name="oco_distribuidor", nullable=false)
	private Distribuidor distribuidor;
	
	//@Column(columnDefinition="TEXT")
	private String oco_obs_abertura;
	
	private Date oco_dtconclusao;
	
	@Column(length=20)
	private	String oco_concluinte;
	
	//@Column(columnDefinition="TEXT")
	private String oco_obs_conclusao;
	
	
	@OneToMany(mappedBy="ocorrencia", cascade=CascadeType.ALL)
	private Set<Hst_Ocorrencia> hstOcorrencia;
	
	
	/*
	 * construtores
	 */
	
	public Ocorrencia(){
		
	}
	
	/*
	 * metodos
	 */

	public Cliente getCliente() {
		return cliente;
	}

	public void setCliente(Cliente cliente) {
		this.cliente = cliente;
	}

	public Distribuidor getDistribuidor() {
		return distribuidor;
	}

	public void setDistribuidor(Distribuidor distribuidor) {
		this.distribuidor = distribuidor;
	}

	public String getOco_abertopor() {
		return oco_abertopor;
	}

	public void setOco_abertopor(String oco_abertopor) {
		this.oco_abertopor = oco_abertopor;
	}

	public String getOco_concluinte() {
		return oco_concluinte;
	}

	public void setOco_concluinte(String oco_concluinte) {
		this.oco_concluinte = oco_concluinte;
	}

	public Date getOco_data() {
		return oco_data;
	}

	public void setOco_data(Date oco_data) {
		this.oco_data = oco_data;
	}

	public Date getOco_dtconclusao() {
		return oco_dtconclusao;
	}

	public void setOco_dtconclusao(Date oco_dtconclusao) {
		this.oco_dtconclusao = oco_dtconclusao;
	}

	public Long getOco_numero() {
		return oco_numero;
	}

	public void setOco_numero(Long oco_numero) {
		this.oco_numero = oco_numero;
	}

	public String getOco_obs_abertura() {
		return oco_obs_abertura;
	}

	public void setOco_obs_abertura(String oco_obs_abertura) {
		this.oco_obs_abertura = oco_obs_abertura;
	}

	public String getOco_obs_conclusao() {
		return oco_obs_conclusao;
	}

	public void setOco_obs_conclusao(String oco_obs_conclusao) {
		this.oco_obs_conclusao = oco_obs_conclusao;
	}

	public TipoOcorrencia getTipoOcorrencia() {
		return tipoOcorrencia;
	}

	@Override
	public int hashCode() {
		final int PRIME = 31;
		int result = 1;
		result = PRIME * result + ((oco_numero == null) ? 0 : oco_numero.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final Ocorrencia other = (Ocorrencia) obj;
		if (oco_numero == null) {
			if (other.oco_numero != null)
				return false;
		} else if (!oco_numero.equals(other.oco_numero))
			return false;
		return true;
	}

	public void setTipoOcorrencia(TipoOcorrencia tipoOcorrencia) {
		this.tipoOcorrencia = tipoOcorrencia;
	}

	public Set<Hst_Ocorrencia> getHstOcorrencia() {
		return hstOcorrencia;
	}

	public void setHstOcorrencia(Set<Hst_Ocorrencia> hstOcorrencia) {
		this.hstOcorrencia = hstOcorrencia;
	}
	
	public void addHstOcorrencia(Hst_Ocorrencia hst) {		
		this.hstOcorrencia.add(hst);
		hst.setOcorrencia(this);
	}

}

Classe Hst_Ocorrencia

package br.com.europa.modelo;

import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

import br.com.europa.hibernate.Hst_Ocorrencia_pk;

@Entity
public class Hst_Ocorrencia {
	
	/*
	 * membros
	 */
	
	@EmbeddedId 
	private Hst_Ocorrencia_pk id;
	
	@ManyToOne
	@JoinColumn(name="hst_oco_numero", nullable=false, updatable=false, insertable=false)	
	private Ocorrencia ocorrencia;
	
	@Column(length=20)
	private String hst_oco_abertopor;
	
	//@Column(columnDefinition="TEXT")
	private String hst_oco_obs;
	
	/*
	 * construtores
	 */
	
	public Hst_Ocorrencia(){
		
	}

	/*
	 * metodos
	 */
	public String getHst_oco_abertopor() {
		return hst_oco_abertopor;
	}

	public void setHst_oco_abertopor(String hst_oco_abertopor) {
		this.hst_oco_abertopor = hst_oco_abertopor;
	}

	public String getHst_oco_obs() {
		return hst_oco_obs;
	}

	public void setHst_oco_obs(String hst_oco_obs) {
		this.hst_oco_obs = hst_oco_obs;
	}

	public Hst_Ocorrencia_pk getId() {
		return id;
	}

	public void setId(Hst_Ocorrencia_pk id) {
		this.id = id;
	}
/*
	public Ocorrencia getOcorrencia() {
		return ocorrencia;
	}

	public void setOcorrencia(Ocorrencia ocorrencia) {
		this.ocorrencia = ocorrencia;
	}
*/

	public Ocorrencia getOcorrencia() {
		return ocorrencia;
	}

	public void setOcorrencia(Ocorrencia ocorrencia) {
		this.ocorrencia = ocorrencia;
	}
}

Classe Hst_Ocorrencia_pk (para gerar chave primaria da Hst_Ocorrencia)

package br.com.europa.hibernate;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Embeddable;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

import br.com.europa.modelo.Ocorrencia;

@Embeddable
public class Hst_Ocorrencia_pk implements Serializable{
	

	@ManyToOne
	@JoinColumn(name="hst_oco_numero", nullable=false)
	private Ocorrencia ocorrencia;
	
	private Date hst_oco_data;

	public Date getHst_oco_data() {
		return hst_oco_data;
	}

	public void setHst_oco_data(Date hst_oco_data) {
		this.hst_oco_data = hst_oco_data;
	}

	public Ocorrencia getOcorrencia() {
		return ocorrencia;
	}

	public void setOcorrencia(Ocorrencia ocorrencia) {
		this.ocorrencia = ocorrencia;
	}

	@Override
	public int hashCode() {
		final int PRIME = 31;
		int result = 1;
		result = PRIME * result + ((hst_oco_data == null) ? 0 : hst_oco_data.hashCode());
		result = PRIME * result + ((ocorrencia == null) ? 0 : ocorrencia.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final Hst_Ocorrencia_pk other = (Hst_Ocorrencia_pk) obj;
		if (hst_oco_data == null) {
			if (other.hst_oco_data != null)
				return false;
		} else if (!hst_oco_data.equals(other.hst_oco_data))
			return false;
		if (ocorrencia == null) {
			if (other.ocorrencia != null)
				return false;
		} else if (!ocorrencia.equals(other.ocorrencia))
			return false;
		return true;
	}
	
}

Agora a classe de testes:

package br.com.europa.testes.Ocorrencia;

import java.util.Date;

import org.hibernate.Session;

import br.com.europa.hibernate.Hst_Ocorrencia_pk;
import br.com.europa.modelo.Cliente;
import br.com.europa.modelo.Distribuidor;
import br.com.europa.modelo.Hst_Ocorrencia;
import br.com.europa.modelo.Ocorrencia;
import br.com.europa.modelo.TipoOcorrencia;
import br.com.europa.util.HibernateFactory;

public class TestaInsercaoOcorrencia {

	public static void main(String[] args) {
		
		Session session = HibernateFactory.getSession();		
		session.beginTransaction();
		
		/*
		 * seta os dados da ocorrencia
		 */
		
		Ocorrencia ocorrencia = new Ocorrencia();//(Ocorrencia) session.get(Ocorrencia.class, new Long(1));
		ocorrencia.setOco_abertopor("ADMINISTRADOR");
		ocorrencia.setOco_data(new Date());
		ocorrencia.setOco_obs_abertura("Isso é um teste para ver se o campo memo vai aguentar");
				
		/*
		 * pegando um cliente valido 
		 */
		
		Cliente c  = (Cliente) session.get(Cliente.class, new Long(1));
		ocorrencia.setCliente(c);
		
		/*
		 * pegando um distribuidor valido
		 */
		
		Distribuidor d = (Distribuidor) session.get(Distribuidor.class, new Long(1));
		ocorrencia.setDistribuidor(d);
		
		/*
		 * pegando um tipo de ocorrencia
		 */
		
		TipoOcorrencia tpo = (TipoOcorrencia) session.get(TipoOcorrencia.class, new Long(1));
		ocorrencia.setTipoOcorrencia(tpo);
		
		
		/*
		 * Historico
		 */
		

		Hst_Ocorrencia hst = new Hst_Ocorrencia();
		hst.setHst_oco_obs("Teste 1");
		hst.setHst_oco_abertopor("ADMINISTRADOR");
		ocorrencia.addHstOcorrencia(hst);
						
		session.save(ocorrencia);
		session.getTransaction().commit();		
		
	}
	
}

Quando eu executo a classe para testar ele me da o seguinte erro

Exception in thread “main” java.lang.NullPointerException
at br.com.europa.modelo.Ocorrencia.addHstOcorrencia(Ocorrencia.java:185)
at br.com.europa.testes.Ocorrencia.TestaInsercaoOcorrencia.main(TestaInsercaoOcorrencia.java:61)

Se eu salvar a ocorrencia e depois salvar os historicos tudo bem, mas em cascada não funciona. O que pode estar acontecendo?

Grato
Celso

Pessoal faltou uma coisa na classe Ocorrencia

@OneToMany(mappedBy="ocorrencia", cascade=CascadeType.ALL)
private Set<Hst_Ocorrencia> hstOcorrencia = new HashSet<Hst_Ocorrencia>();

Agora o erro é esse

Exception in thread “main” org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): br.com.europa.modelo.Hst_Ocorrencia
at org.hibernate.id.Assigned.generate(Assigned.java:33)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:91)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:186)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:175)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:98)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:502)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:494)
at org.hibernate.engine.CascadingAction$1.cascade(CascadingAction.java:134)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:213)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:157)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:108)
at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:290)
at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:185)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:160)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:108)
at org.hibernate.engine.Cascade.cascade(Cascade.java:248)
at org.hibernate.event.def.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:410)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:299)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:167)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:101)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:186)
at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:33)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:175)
at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:27)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:530)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:518)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:514)
at br.com.europa.testes.Ocorrencia.TestaInsercaoOcorrencia.main(TestaInsercaoOcorrencia.java:62)