Herança Hibrnate

Prezados, estou desenvolvendo uma aplicaçao com a seguinte estrutura:

Classe proprietario, Classe Embarcaçao(possuiu relacionamento 1:n e tem uma FK(id_proprietario)), Classe JetSki(que herda da classe embarcacao possui uma FK(id_embarcacao)) e uma Classe Lancha(que herda da classe embarcacao possui uma FK(id_embarcacao)).

Proprietario POJO

@Entity
@Table(name = "proprietario")
public class Proprietario implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	@Column(name = "idProprietario", nullable = false)
	private Integer idProprietario;

	@Column(name = "proprietarioNome", nullable = false)
	private String proprietarioNome;

	@Column(name = "numeroArrais", nullable = false)
	private String numeroArrais;

	@Column(name = "cpf", nullable = false)
	private String cpf;

	@Column(name = "telefone", nullable = false)
	private String telefone;

	@OneToMany(mappedBy = "proprietario", fetch = FetchType.LAZY)
	@Cascade(CascadeType.ALL)
	private Collection<Embarcacao> embarcacoes;

Embarcacao POJO


@Entity
@Table(name = "embarcacao")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "tipo_embarcacao",discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorValue("0")
public class Embarcacao implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	@Column(name = "idEmbarcacao", nullable = false)
	private Integer idEmbarcacao;

	@Column(name = "nomeEmbarcacao", nullable = false)
	private String nomeEmbarcacao;

	@Column(name = "inscricaoEmbarcacao", nullable = false)
	private String inscricaoEmbarcacao;
	
	@Column(name = "tipoEmbarcacao", nullable = false)
	private Integer tipoEmbarcacao;

	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "idProprietario", insertable = true, updatable = true)
	@Fetch(FetchMode.JOIN)
	@Cascade(CascadeType.SAVE_UPDATE)
	private Proprietario proprietario;

Jetski POJO:

@Entity
@DiscriminatorValue("1")
public class JetSki extends Embarcacao {
	private static final long serialVersionUID = 1L;
	@IndexColumn(name = "idJetski_UNIQUE")
	@Id
	@Column(name = "idJetski", nullable = false)
	private Integer idJetski;

	@Column(name = "jetComprimento", nullable = false)
	private String jetComprimento;

	@Column(name = "jetPotenciaMotor", nullable = false)
	private String jetPotenciaMotor;

	@Column(name = "jetAno", nullable = false)
	private String jetAno;

	@Column(name = "jetQuantidadePessoas", nullable = false)
	private String jetQuantidadePessoas;

	@Column(name = "jetModelo", nullable = false)
	private String jetModelo;

	@Column(name = "jetMarca", nullable = false)
	private String jetMarca;

	@Column(name = "jetTipoMotor", nullable = false)
	private String jetTipoMotor;

	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "embarcacao_idEmbarcacao")
	private Embarcacao embarcacao;

Lancha POJO

@Entity
@DiscriminatorValue("2")
public class Lancha extends Embarcacao {
	private static final long serialVersionUID = 1L;


	@IndexColumn(name = "idLancha_UNIQUE")
	@Id
	@Column(name = "idLancha", nullable = false)
	private Integer idLancha;

	@Column(name = "lanchaComprimento", nullable = false)
	private String lanchaComprimento;

	@Column(name = "lanchaPotenciaMotor", nullable = false)
	private String lanchaPotenciaMotor;

	@Column(name = "lanchaAno", nullable = false)
	private String lanchaAno;

	@Column(name = "lanchaQuantidadePessoas", nullable = false)
	private String lanchaQuantidadePessoas;

	@Column(name = "lanchaModelo", nullable = false)
	private String lanchaModelo;

	@Column(name = "lanchaMarca", nullable = false)
	private String lanchaMarca;

	@Column(name = "lanchaTipoMotor", nullable = false)
	private String lanchaTipoMotor;

	@Column(name = "lanhaAcessorios", nullable = false)
	private String lanchaAcessorios;

	@Column(name = "lanchaQuantidadeMotores", nullable = false)
	private String lanchaQuantidadeMotores;

	@Column(name = "lanchaCapacidadeTanque", nullable = false)
	private String lanchaCapacidadeTanque;

	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "embarcacao_idEmbarcacao")
	private Embarcacao embarcacao;

Meu Banco:

CREATE TABLE embarcacao (
  idEmbarcacao INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  idProprietario INTEGER UNSIGNED NOT NULL,
  nomeEmbarcacao TEXT NOT NULL,
  inscricaoEmbarcacao TEXT NOT NULL,
  PRIMARY KEY(idEmbarcacao),
  INDEX embarcacao_FKIndex1(idProprietario)
);

CREATE TABLE jetski (
  idJetski INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  embarcacao_idEmbarcacao INTEGER UNSIGNED NOT NULL,
  jetskiComprimento VARCHAR(10) NULL,
  jetPotenciaMotor VARCHAR(10) NULL,
  jetAno VARCHAR(10) NULL,
  jetQuantidadePessoas CHAR(6) NULL,
  jetModelo TEXT NULL,
  jetMarca TEXT NULL,
  jetTipoMotor TEXT NULL,
  PRIMARY KEY(idJetski),
  INDEX jetski_FKIndex1(embarcacao_idEmbarcacao)
);

CREATE TABLE lancha (
  idLancha INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  embarcacao_idEmbarcacao INTEGER UNSIGNED NOT NULL,
  lanchaComprimento VARCHAR(10) NULL,
  lanchaPotenciaMotor VARCHAR(10) NULL,
  lanchaAno VARCHAR(10) NULL,
  lanchaQuantidadePessoas CHAR(6) NULL,
  lanchaModelo TEXT NULL,
  lanchaMarca TEXT NULL,
  lanchaTipoMotor TEXT NULL,
  lanhaAcessorios TEXT NULL,
  lanchaQuantidadeMotores CHAR(6) NULL,
  lanchaCapacidadeTanque TEXT NULL,
  PRIMARY KEY(idLancha),
  INDEX lancha_FKIndex1(embarcacao_idEmbarcacao)
);

CREATE TABLE proprietario (
  idProprietario INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  proprietarioNome TEXT NOT NULL,
  numeroArrais TEXT NOT NULL,
  cpf CHAR(11) NOT NULL,
  telefone CHAR(15) NOT NULL,
  PRIMARY KEY(idProprietario)
);

Estou conseguindo inserir o proprietario, a minha duvida e a seguinte como inserir uma embarcacao?
Seria algo assim:

public static void main(String[] args) throws Exception {

Embarcacao registro = new Embarcacao();

		registro.setidEmbarcacao(1);
		registro.setinscricaoEmbarcacao("IM333116");
		registro.setnomeEmbarcacao("Bodas de ouro");
		registro.setProprietario(proprietario1);
		registro.setTipoEmbarcacao(1);

JetSki jetski1 = new JetSki();
		jetski1.setidJetski(1);
		jetski1.setJetAno("2010");
		jetski1.setJetComprimento("2,50 m");
		jetski1.setJetMarca("Susuki");
		jetski1.setJetModelo("ix150");
		jetski1.setJetPotenciaMotor("750 cc");
		jetski1.setJetQuantidadePessoas("2");
		jetski1.setJetTipoMotor("2 Tempos");

Por acaso as tabelas já existem no banco de dados? ou foram criadas dinâmicamente pelo Hibernate?
Se o banco já existe e não tem como mudar vc terá que resolver usando a anotação @Inheritance(strategy=InheritanceType.JOINED) que é o que estará acontecendo.
Mas se há como modificar a estrutura do banco, pessoalmente nestes casos eu deixaria o Hibernate criar e se preciso depois fazer algum tunning nas tabelas.
Pelo modelo que apresentou o mais recomendável seria uma estratégia do tipo table_per_class pois será mais performática.
Em qualquer um dos casos, como sua classe extenderá a superclasse, vc trabalhará apenas com a classe filha.
Um exemplo deste último mapeamento você pode encontrar neste link: http://demoiselle.sourceforge.net/docs/guide-nimble/1.0.4/html/eclipsesample.html

Cara eu tenho como alterar o banco, criei no mysql, mais nao entendi muito bem, as anotaçoes que estao nas minhas classes estao certas?

Mudei minha herança, segue:

[code]@Entity
@Table(name = “embarcacao”)
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name=“TIPO_EMBARCACAO”, discriminatorType=DiscriminatorType.INTEGER)

public class Embarcacao implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@Column(name = "idEmbarcacao", nullable = false)
private Integer idEmbarcacao;

@Column(name = "nomeEmbarcacao", nullable = false)
private String nomeEmbarcacao;

@Column(name = "inscricaoEmbarcacao", nullable = false)
private String inscricaoEmbarcacao;

@Column(name = "tipoEmbarcacao", nullable = false)
private Integer tipoEmbarcacao;

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "idProprietario", insertable = true, updatable = true)
@Fetch(FetchMode.JOIN)
@Cascade(CascadeType.SAVE_UPDATE)
private Proprietario proprietario;

public Embarcacao() {
	this.idEmbarcacao = null;
	this.nomeEmbarcacao = null;
	this.inscricaoEmbarcacao = null;

}

@Override
public String toString() {
	return "Embarcacao [idEmbarcacao=" + idEmbarcacao + ", nomeEmbarcacao="
			+ nomeEmbarcacao + ", inscricaoEmbarcacao="
			+ inscricaoEmbarcacao + "tipoEmbarcacao=" + tipoEmbarcacao+"]";
}[/code]

[code]@Entity
@Table(name=“jetski”)
@DiscriminatorValue(“1”)
public class JetSki extends Embarcacao {
private static final long serialVersionUID = 1L;
//@IndexColumn(name = “idJetski_UNIQUE”)
//@Id
@Column(name = “idJetski”, nullable = false)
private Integer idJetski;

@Column(name = "jetComprimento", nullable = false)
private String jetComprimento;

@Column(name = "jetPotenciaMotor", nullable = false)
private String jetPotenciaMotor;

@Column(name = "jetAno", nullable = false)
private String jetAno;

@Column(name = "jetQuantidadePessoas", nullable = false)
private String jetQuantidadePessoas;

@Column(name = "jetModelo", nullable = false)
private String jetModelo;

@Column(name = "jetMarca", nullable = false)
private String jetMarca;

@Column(name = "jetTipoMotor", nullable = false)
private String jetTipoMotor;

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "embarcacao_idEmbarcacao")
private Embarcacao embarcacao;[/code]

Ta dando o erro quando tento inserir

Hibernate: /* get current state br.ucb.pojo.Proprietario */ select proprietar_.idProprietario, proprietar_.cpf as cpf3_, proprietar_.numeroArrais as numeroAr3_3_, proprietar_.proprietarioNome as propriet4_3_, proprietar_.telefone as telefone3_ from proprietario proprietar_ where proprietar_.idProprietario=? Exception in thread "main" org.hibernate.HibernateException: Falha de inclusão no BD: at br.ucb.hibernate.JetSkiHibernate.inclui(JetSkiHibernate.java:49) at br.ucb.aplicacao.TesteEmbProp.inclusaoDeJetSki(TesteEmbProp.java:104) at br.ucb.aplicacao.TesteEmbProp.main(TesteEmbProp.java:190) Caused by: org.hibernate.PropertyValueException: not-null property references a null or transient value: br.ucb.pojo.JetSki.tipoEmbarcacao at org.hibernate.engine.Nullability.checkNullability(Nullability.java:100) at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:312) at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:203) at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:143) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210) at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195) at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50) at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93) at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:713) at org.hibernate.impl.SessionImpl.save(SessionImpl.java:701) at org.hibernate.impl.SessionImpl.save(SessionImpl.java:697) at br.ucb.hibernate.JetSkiHibernate.inclui(JetSkiHibernate.java:38)

Se você pode alterar o banco, apague todas as tabelas e deixe o hibernate cria-las. Para isso use <property name=“hibernate.hbm2ddl.auto” value=“update” /> no arquivo de configuração.
Você viu o exemplo no link que passei?

Com relação as suas classes:

  • A sua super classe só precisa da anotação @MappedSuperclass, as propriedades podem ficar do jeito que está.
  • As classes filhas (ex: jetski) não precisam da propriedade Embarcação, pois já extendem a classe.
    { @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = “embarcacao_idEmbarcacao”)
    private Embarcacao embarcacao; }

Não sei em que nível já está seu projeto e se está usando algum framework para ajudar.
Mas caso se interesse em usar o Demoiselle (http://www.frameworkdemoiselle.gov.br/) poderíamos ajudá-lo de forma mais efetiva.