Como mapear no JPA TABLE_PER_CLASS herança para [columns] e [sequences] diferentes?

Olá, estou tendo dificuldade em fazer o seguinte mapeamento, onde tenho uma tabela por subclasse, usando JPA 2. Segue classe abstrata(superclasse) abaixo:

@Entity @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) public abstract class FieldDefinition extends BaseEntity { @Id @GeneratedValue(strategy=GenerationType.SEQUENCE) protected Integer id; }e na subclasse:

[code]@Entity
@Table(name=“integer_fields”)
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
@AttributeOverride(name=“id”, column=@Column(name=“integer_field_id”) )
@SequenceGenerator(name=“generator”, sequenceName=“integer_fields_integer_field_id_seq”)
public class IntegerField extends FieldDefinition {

}[/code]no caso o atributo id é compartilhado entre as subclasses, e estas tem chave primárias diferentes, e consequente nome se sequences diferentes.
do jeito que está acima, ganho o seguinte erro:

[quote]org.springframework.dao.InvalidDataAccessResourceUsageException:
could not get next sequence value; SQL [select nextval (‘hibernate_sequence’)];
nested exception is org.hibernate.exception.SQLGrammarException: could not get next sequence value[/quote]
alguém saberia como resolver mapeando a partir da subclasse?

tinha visto algumas abordagens que mapeia a superclasse com @MappedSuperclass, onde na classe FieldDefinition ao invés de usar @Entity, usar @MappedSuperclass, mas isso implicará no seguinte erro abaixo, pois eu tenho outra classe, que tem um relacionamento @OneToMany para FieldDefinition

classe InfoRequest, que tem relacionamento OneToMany com FieldDefinition(abstrata)

@Entity @Table(name="info_requesters") public class InfoRequest { ... @OneToMany(cascade=CascadeType.ALL) @JoinColumn(name="info_request_id") private Set<FieldDefinition> fieldDefinition; }
erro ao tentar modificar classe FieldDefinition, usando @MappedSuperclass, ao invés de @Entity

resumindo, apenas estou realçando o porque não usei @MappedSuperclass para mapear a superclasse, FieldDefinition, apesar de este não ser o erro em específico, permanecendo o primeiro acima.

Lá no seu Set, você pode mapear com @CollectionOfElements.

     @CollectionOfElements
     @JoinTable(name="fieldDefinitionTable",
     joinColumns=@JoinColumn(name="ID_ENTIDADE_DONA_DA_LISTA",
            referencedColumnName="ID_FIELD_DEFINITION"))
     private Set<FieldDefinition> fieldDefinition;

Tenta aí

eu acredito que não exista a necessidade de mapear novamente isso

@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)  

na classe IntegerField

caso você esteja com problema com o atributo ID ser utilizado em várias tabelas, você pode utilizar um @TableGenerator que controla e distribui os ID para todas as tabelas que extendem essa classe.

você ja tentou isso?

[quote=oddy.silva]Lá no seu Set<T>, você pode mapear com @CollectionOfElements.

@CollectionOfElements @JoinTable(name="fieldDefinitionTable", joinColumns=@JoinColumn(name="ID_ENTIDADE_DONA_DA_LISTA", referencedColumnName="ID_FIELD_DEFINITION")) private Set&lt;FieldDefinition&gt; fieldDefinition;Tenta aí
[/quote]
entendi, mas eu não poderia utilizar CollectionOfElements, porque a classe FieldDefinition é uma classe abstrata que não está mapeada para uma tabela.

[quote=pinheiro.cc]eu acredito que não exista a necessidade de mapear novamente isso

é vero, efeito copy-paste aqui no tópico. ignorem!

não tentei porque inicialmente não tinha achado que se aplicava ao meu caso por conta das sequences serem diferentes.

para explicar melhor o caso tenho o seguinte cenário no modelo de classe e banco, respectivamente

obs: analisando a priori estes modelos individualmente, parece uma idéia inútil, mas removi bastantes informações afim de facilitar entendimento, como idéia básica para mapear estes relacionamentos.

fazendo uns testes a força bruta, resgistrando tentativa falha, ele gerou o seguinte jpql

[quote]Hibernate: insert into owners (logo_id, name) values (?, ?)
Hibernate: select currval(‘owners_owner_id_seq’)
Hibernate: insert into info_requesters (final_date, owner_id) values (?, ?)
Hibernate: select currval(‘info_requesters_info_request_id_seq’)
Hibernate: select nextval (‘integer_fields_integer_field_id_seq’)
Hibernate: insert into integer_fields (label, required, info_request_id, integer_field_id) values (?, ?, ?, ?)
Hibernate: update FieldDefinition set info_request_id=? where integer_field_id=?[/quote]
reparem que na última linha ele gerou uma operação de update para classe abstrata onde não deveria, apesar de na linha anterior ter feito um insert na tabela correta mapeada a partir da subclasse. segue como ficou mapeamento para gerar comportamento acima:

classe abstrata FieldDefinitionFiz propositalmente declaração dos campos na superclasse, pois não consegui rescrevê-los na subclasse demonstrado no 1º post deste tópico

[code]@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class FieldDefinition extends BaseEntity {

private static final long serialVersionUID = 8428299722798237491L;

// sei que este mapeamento abaixo está errado na superclasse, mas não consegui específicá-los na subclasse, então fiz teste de força bruta que não deu certo
@Id @Column(name=“integer_field_id”)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator=“generator”)
@SequenceGenerator(name=“generator”, sequenceName=“integer_fields_integer_field_id_seq”)
protected Integer id;
}[/code]

subclasse IntegerField

@Entity @Table(name="integer_fields") public class IntegerField extends FieldDefinition { ... }

classe InfoRequest que possui relacionamento OneToMany com classe abstrata FieldDefinition, do tipo Set

@Entity @Table(name="info_requesters") public class InfoRequest extends BaseEntity { ... @OneToMany(cascade=CascadeType.ALL) @JoinColumn(name="info_request_id") private Set<FieldDefinition> fieldDefinition; }

segue abaixo como ficou chamada para metodo de teste do log acima identificado na geração do hql

[code]@Test public void testBasic() {

InfoRequest infoRequest = createInfoRequest(); // cria instancia apenas da entidade infoRequest
	
IntegerField fieldAge = new IntegerField(); // criando item 
fieldAge.setLabel("age");
fieldAge.setRequired(true);
fieldAge.setInfoRequest( infoRequest );
	
infoRequest.add( fieldAge ); // adicionando item ao infoRequest
infoRequestRepository.create( infoRequest ); // criando, 
	
sync(); // aqui faz em.flush() e em.clear() ... e ele dá erro na chamada flush() no comentário abaixo
	
assertTrue( true );

}[/code]

erro ocorre após executar linha de método acima sync()

[quote]Caused by: java.sql.BatchUpdateException: Entrada em lote 0 update FieldDefinition set info_request_id=107 where integer_field_id=1700 foi abortada. Chame getNextException para ver a causa. ERRO: relação “fielddefinition” não existe
[/quote]
obs: último acima informa uma coisa óbvia, faltando apenas fazer com que ele gere jpql para entidade certa. :?:

uma pergunta vocês sabem como faço para sobrescrever mapeamento da chave primária a partir da subclasse. não é sobrescrever associação ou atributo, é o @Id da superclasse.
no caso tentei fazê-lo da seguinte forma:

super classe FieldDefinition

[code]@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class FieldDefinition extends BaseEntity {

@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
protected Integer id;

...

// movi o atributo de infoRequest para subclasse, no caso IntegerField
// fiz isto acima, porque ele gerava aquele update nada a ver em negrito como descrevi acima -> http://www.guj.com.br/posts/list/206452.java#1049305

}[/code]
subclasse IntegerField

[code]@Entity
@Table(name=“integer_fields”)
@AttributeOverride(name=“id”, column=@Column(name=“integer_field_id”))
public class IntegerField extends FieldDefinition {

@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
protected Integer id;

@ManyToOne
@JoinColumn(name="info_request_id")
private InfoRequest infoRequest;

}[/code]
fazendo isto recebo a seguinte exceção

vi no forum do hibernate sobre onde uma alternativa seria, tipo colocando uma anotação no método get, mas não funfou/funcionou