[Resolvido] Hibernate: Chave composta com sequence

Pessoal preciso mais uma vez de ajuda.

As vezes eu tento entender algumas coisas que os profissionais de banco de dados fazem.
Eu preciso fazer um mapeamento no hibernate do modelo em anexo.
É apenas um pedaço MUITO reduzido do meu problema.

O banco é o Oracle.

Criaram uma tabela com uma sequence: NO_SEQ_PROD_CONS_FINAL
Eu fiz o mapeamento assim:

@Entity
@Table(name = "PRODUTO_CONSUMIDOR_FINAL", schema = "CORPORATIVO")
@SequenceGenerator(name = "SEQ_PROD_CONS_FINAL", sequenceName = "NO_SEQ_PROD_CONS_FINAL")
public class ProdutoConsumidorFinal implements java.io.Serializable {

	@Id
	@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="SEQ_PROD_CONS_FINAL")
	@Column(name = "NO_SEQ_PROD_CONS_FINAL", unique = true, nullable = false, precision = 10, scale = 0)
	private long noSeqProdConsFinal;

}

Na próxima tabela colocaram a mesma sequence como chave primária.
E mapeei:

@Entity
@Table(name = "PRODUTO_FINANCEIRO_CONS_FINAL", schema = "PRODFIN")
@SequenceGenerator(name = "SEQ_PROD_CONS_FINAL", sequenceName = "NO_SEQ_PROD_CONS_FINAL")
public class ProdutoFinanceiroConsFinal implements java.io.Serializable {

	private static final long serialVersionUID = 9202223600458380307L;

	@Id
	@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_PROD_CONS_FINAL")
	@Column(name = "NO_SEQ_PROD_CONS_FINAL", unique = true, nullable = false, precision = 10, scale = 0)
	private long noSeqProdConsFinal;

}

Na próxima tabela, colocaram como chave primária a mesma sequence e mais uma data. :cry:
Não estou sabendo mapear isso.
O hibernate tools mapeou assim.

@Entity
@Table(name = "VIG_PROD_FINANC_CONS_FINAL", schema = "PRODFIN")
public class VigProdFinancConsFinal implements java.io.Serializable {

	@EmbeddedId
	@AttributeOverrides({
			@AttributeOverride(name = "noSeqProdConsFinal", column = @Column(name = "NO_SEQ_PROD_CONS_FINAL", nullable = false, precision = 10, scale = 0)),
			@AttributeOverride(name = "dtIniVig", column = @Column(name = "DT_INI_VIG", nullable = false, length = 7)) })
	private VigProdFinancConsFinalId id;

}

E o id pra essa tabela, chave composta: sequence + date

@Embeddable
public class VigProdFinancConsFinalId implements java.io.Serializable {

	@Column(name = "NO_SEQ_PROD_CONS_FINAL", nullable = false, precision = 10, scale = 0)
	private long noSeqProdConsFinal;

	@Temporal(TemporalType.DATE)
	@Column(name = "DT_INI_VIG", nullable = false, length = 7)
	private Date dtIniVig;

}

Nas duas primeiras tabelas eu coloquei a sequence e parece estar correto, mas neste ultimo caso com chave composta ta complicado.
O validate do hibernate reclama da sequence NO_SEQ_PROD_CONS_FINAL na ultima tabela.

Tem tabela com 5 chaves formando a chave composta. :cry: :cry: :cry:

Alguém pode me ajudar ??


Fala cara, tinha entendido uma coisa mas parece ser outra. Ve se isso te ajuda: http://uaihebert.com/?p=1622&page=8 | http://uaihebert.com/?p=1622&page=9

Normal! Também não entendo…

Aqui tem mais outro exemplo mais direto:

[code]
public class Parent {

@Id
private Long someId;

@OneToMany(mappedBy="pk.parent")
@JoinColumns([@JoinColumn(name="someId"), @JoinColumn(name="otherField")])
private Set<Child> children

}

public class Child {
private ChildPK pk;

private String someReallyOtherField;

}

class ChildPK {
@ManyToOne
@JoinColumn(name=“someId”)
Parent parent;

String otherField;

}[/code]http://www.coderanch.com/t/463087/ORM/databases/Hibernate-composite-key-foreign-key

Então…
Mapear chave composta eu até sei, mas o problema é que essa chave é composta com uma sequence.
Acho q tenho q mapear a sequence e dizer q ela é chave junto da data. (onde já se viu isso ? :x )
Não sei se tenho q mapear na Entidade ou na classe Id dessa identidade.

Isso q não to sabendo fazer.
Tenho outras chaves compostas com campos comuns e funciona.

[quote=fdiaz2011]Então…
Mapear chave composta eu até sei, mas o problema é que essa chave é composta com uma sequence.
Acho q tenho q mapear a sequence e dizer q ela é chave junto da data. (onde já se viu isso ? :x )
Não sei se tenho q mapear na Entidade ou na classe Id dessa identidade.

Isso q não to sabendo fazer.
Tenho outras chaves compostas com campos comuns e funciona.
[/quote]
Isso que imaginei, mapear como chave composta o NO_SEQ_PROD_CONS_FINAL + Data, por isso mostrei o exemplo. O campo NO_SEQ_PROD_CONS_FINAL em VigProdFinancConsFinal não recebe sequence nenhuma, só é uma chave estrangeira e faz parte da chave primária. Foi o que entendi pelo desenho, ou nessa tabela a sequence é atribuída (nextval)? Imagino que não pois daria erro de integridade referencial, só tem que mesmo setar com o valor do Id da tabela pai.

Da forma que passei, veja oq o validate do hibernate diz:

INFO: table found: PRODFIN.VIG_PROD_FINANC_CONS_FINAL
26/04/2013 08:13:52 org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: columns: [cd_tipo_km_acum, cd_usuario, qt_km_acum_prom, dt_incl, qt_km_acum_parc_pgto, dt_ini_vig, vr_prod, vr_adesao, dt_fim_vig, no_parc_pgto_acum_km, no_seq_prod_cons_final, dt_alter, dt_inat, vr_parc_prod, qt_km_acum_adesao]
26/04/2013 08:13:53 org.hibernate.tool.hbm2ddl.DatabaseMetadata getTableMetadata
INFO: table not found: NO_SEQ_PROD_CONS_FINAL
Exception in thread "main" java.lang.ExceptionInInitializerError
	at java.lang.J9VMInternals.initialize(J9VMInternals.java:218)
	at java.lang.J9VMInternals.initialize(J9VMInternals.java:161)
	at Produtos.main(Produtos.java:7)
Caused by: org.hibernate.HibernateException: Missing sequence or table: NO_SEQ_PROD_CONS_FINAL
	at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1094)
	at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:116)
	at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:317)
	at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1294)
	at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:915)
	at ipp.mv.produtosfinanceiros.dao.GenericDAO.<clinit>(GenericDAO.java:25)
	at java.lang.J9VMInternals.initializeImpl(Native Method)
	at java.lang.J9VMInternals.initialize(J9VMInternals.java:196)
	... 2 more

Essa é a forma q estava eq dá essa msg q postei acima

@Entity
@Table(name = "PRODUTO_FINANCEIRO_CONS_FINAL", schema = "PRODFIN")
@SequenceGenerator(name = "SEQ_PROD_CONS_FINAL", sequenceName = "NO_SEQ_PROD_CONS_FINAL")
public class ProdutoFinanceiroConsFinal implements java.io.Serializable {

	private static final long serialVersionUID = 9202223600458380307L;

	@Id
	@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_PROD_CONS_FINAL")
	@Column(name = "NO_SEQ_PROD_CONS_FINAL", unique = true, nullable = false, precision = 10, scale = 0)
	private long noSeqProdConsFinal;

        @OneToMany(fetch = FetchType.LAZY, mappedBy = "produtoFinanceiroConsFinal")
	private Set<VigProdFinancConsFinal> vigProdFinancConsFinals = new HashSet<VigProdFinancConsFinal>(0);

}

@Entity
@Table(name = "VIG_PROD_FINANC_CONS_FINAL", schema = "PRODFIN")
public class VigProdFinancConsFinal implements java.io.Serializable {

	@EmbeddedId
	@AttributeOverrides({
			@AttributeOverride(name = "noSeqProdConsFinal", column = @Column(name = "NO_SEQ_PROD_CONS_FINAL", nullable = false, precision = 10, scale = 0)),
			@AttributeOverride(name = "dtIniVig", column = @Column(name = "DT_INI_VIG", nullable = false, length = 7)) })
	private VigProdFinancConsFinalId id;

        @ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "NO_SEQ_PROD_CONS_FINAL", nullable = false, insertable = false, updatable = false)
	private ProdutoFinanceiroConsFinal produtoFinanceiroConsFinal;

}

[color=red]Fiz uma mudança com base no exemplo que vc me passou.
Ficou assim:[/color]

ProdutoFinanceiroConsFinal

@OneToMany(fetch = FetchType.LAZY, mappedBy = "id.produtoFinanceiroConsFinal")
private Set<VigProdFinancConsFinal> vigProdFinancConsFinals = new HashSet<VigProdFinancConsFinal>(0);

VigProdFinancConsFinal eu tirei o relacionamento e coloquei na classe Id dela

VigProdFinancConsFinalId

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "noSeqProdConsFinal", nullable = false, insertable = false, updatable = false)
private ProdutoFinanceiroConsFinal produtoFinanceiroConsFinal;

/*@Column(name = "NO_SEQ_PROD_CONS_FINAL", nullable = false, precision = 10, scale = 0)
private long noSeqProdConsFinal;*/

Parece q funcionou ou pelo menos o erro mudou.
Ai ele dá a msg:

INFO: table found: PRODFIN.VIG_PROD_FINANC_CONS_FINAL
26/04/2013 09:04:46 org.hibernate.tool.hbm2ddl.TableMetadata <init>
INFO: columns: [cd_tipo_km_acum, cd_usuario, qt_km_acum_prom, dt_incl, qt_km_acum_parc_pgto, dt_ini_vig, vr_prod, vr_adesao, dt_fim_vig, no_parc_pgto_acum_km, no_seq_prod_cons_final, dt_alter, dt_inat, vr_parc_prod, qt_km_acum_adesao]
Exception in thread "main" java.lang.ExceptionInInitializerError
	at java.lang.J9VMInternals.initialize(J9VMInternals.java:218)
	at java.lang.J9VMInternals.initialize(J9VMInternals.java:161)
	at ProdutosFinanceiros.main(ProdutosFinanceiros.java:7)
Caused by: org.hibernate.HibernateException: Missing column: noSeqProdConsFinal in PRODFIN.VIG_PROD_FINANC_CONS_FINAL
	at org.hibernate.mapping.Table.validateColumns(Table.java:254)
	at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1083)
	at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:116)
	at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:317)
	at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1294)
	at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:915)
	at ipp.mv.produtosfinanceiros.dao.GenericDAO.<clinit>(GenericDAO.java:25)
	at java.lang.J9VMInternals.initializeImpl(Native Method)
	at java.lang.J9VMInternals.initialize(J9VMInternals.java:196)
	... 2 more

O pessoal me dá um modelo todo complicado, com coisas fora do padrão e acham que tenho q entender oq eles qrem.
Ou seja, o entendimento que foi errado e estava fazendo algo mais complicado.

Depois de ver tantas coisas bizarras aqui, pensei q era mais uma delas. hehe

Obrigado pela ajuda !!