Hibernate e Primary Key composta

Boa tarde,

  alguém sabe como declarar uma chave primária composta no hibernate?

Obrigado pela ajuda,

         Thiago Varella

Olá Thiago

Veja abaixo o exemplo de uma cascata de quatro tabelas que desenvolvemos ao testar o Hibernate no inicio de um de nossos projetos:

SQL> DESC XPAIS
Name      Type         Nullable Default Comments 
--------- ------------ -------- ------- -------- 
ID_PAIS   NUMBER                                 
NOME_PAIS VARCHAR2(30) Y                         

SQL> DESC XESTADO
Name      Type         Nullable Default Comments 
--------- ------------ -------- ------- -------- 
ID_PAIS   NUMBER                                 
ID_ESTADO NUMBER                                 
NM_ESTADO VARCHAR2(30) Y                         

SQL> DESC XCIDADE
Name           Type         Nullable Default Comments 
-------------- ------------ -------- ------- -------- 
ID_PAIS        NUMBER                                 
ID_ESTADO_NOVO NUMBER                                 
ID_CIDADE      NUMBER                                 
NM_CIDADE      VARCHAR2(30) Y                         

SQL> DESC XBAIRRO
Name      Type         Nullable Default Comments 
--------- ------------ -------- ------- -------- 
ID_CIDADE NUMBER                                 
ID_ESTADO NUMBER                                 
ID_PAIS   NUMBER                                 
ID_BAIRRO NUMBER                                 
NM_BAIRRO VARCHAR2(30) Y                         

(OBS: Todos os campos que começam com ID são chaves)

Veja abaixo os arquivos de mapeamento para essas tabelas:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>
	<class name="com.systemhaus.antara.util.servidor.XPais" table="XPAIS">
		<id name="idPais" type="java.lang.Integer" column="ID_PAIS">
			<generator class="increment"/>
		</id>
		<property name="nmPais" type="java.lang.String" column="NOME_PAIS"/>
	</class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>
	<class name="com.systemhaus.antara.util.servidor.XEstado" table="XESTADO">
		<composite-id name="id" class="com.systemhaus.antara.util.servidor.XEstadoId">
			<key-property name="idEstado" type="java.lang.Integer" column="ID_ESTADO"/>
			<key-many-to-one name="pais" class="com.systemhaus.antara.util.servidor.XPais" column="id_pais"/>
		</composite-id>
		<property name="nmEstado" type="java.lang.String" column="NM_ESTADO"/>
	</class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>
	<class name="com.systemhaus.antara.util.servidor.XCidade" table="XCIDADE">
		<composite-id name="id" class="com.systemhaus.antara.util.servidor.XCidadeId">
			<key-many-to-one name="estado" class="com.systemhaus.antara.util.servidor.XEstado">
				<!-- A ordem das colunas aqui deve ser equivalente a ordem 
					 das chaves no composite-id de XEstado 
					 (se os nomes dos campos forem diferentes é necessário
					  especificá-los em tags column) -->
				<column name="ID_ESTADO_NOVO"/>
				<column name="ID_PAIS"/>
			</key-many-to-one>
			<key-property name="idCidade" type="java.lang.Integer" column="ID_CIDADE"/>			
		</composite-id>
		<property name="nmCidade" type="java.lang.String" column="NM_CIDADE"/>
	</class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>
	<class name="com.systemhaus.antara.util.servidor.XBairro" table="XBAIRRO">
		<composite-id name="id" class="com.systemhaus.antara.util.servidor.XBairroId">
			<key-many-to-one name="cidade" class="com.systemhaus.antara.util.servidor.XCidade">
				<!-- Ordem dos campos em XEstado -->
				<column name="ID_ESTADO"/>
				<column name="ID_PAIS"/>
				<!-- Mesma ordem do composite-id de XCidade
					 1o. campos do id do estado
					 2o. campo  do id da cidade  -->
				<column name="ID_CIDADE"/>
			</key-many-to-one>
			<key-property name="idBairro" type="java.lang.Integer" column="ID_BAIRRO"/>			
		</composite-id>
		<property name="nmBairro" type="java.lang.String" column="NM_BAIRRO"/>
	</class>
</hibernate-mapping>

[/quote]

Espero ter conseguido ajudar …

Atenciosamente,
Gabriel.

E se minha as primaries da minha tabela nao sao de outras?
E seu a minha tabela ESTADO tivesse como chave as colunas ID_PAIS e ID_ESTADO mas nao existisse a tabela PAIS ?? Como eu faria ???

Usamos primary para nao permitir a duplicidade de registro em uma tabela, portanto podemos ter mais do que uma coluna somente, e nem sempre existe uma referencia em outra tabela.

Como eu faço esse mapeamente de colunas???! :roll:

Use só o key-property, mais ou menos assim:

<composite-id>
  <key-property name="idPais" type="java.lang.Integer" column="id_pais"/>
  <key-property name="idEstado" type="java.lang.Integer" column="id_estado"/>
</composite-id>

Deve funcionar!!!

Fallow

18:45:15,056 ERROR XMLHelper:48 - Error parsing XML: XML InputStream(8) Element type "key-property" must be declared.
18:45:15,056 ERROR XMLHelper:48 - Error parsing XML: XML InputStream(9) Element type "key-property" must be declared.
18:45:15,076 ERROR XMLHelper:48 - Error parsing XML: XML InputStream(10) The content of element type "composite-id" must match "(property)+".

:shock: :shock: :shock: :shock:

Realmente estranho, pois é essa construção q eu uso aqui e funciona! :shock:

Inclusive vc a encontra na documentação!! De uma olhada no reference, na parte 5.1.5 Composite-ids…

Que versão vc está usando???