Pergunta

Temos uma tabela em nosso sistema que pares de chave de recurso lojas / valor. Há duas colunas para armazenar o valor; uma coluna VARCHAR para valores menores e um CLOB para valores maiores. No lado do Java, que são instanciado em uma das duas classes, uma StandardResourceBundleValue ou um LargeResourceBundleValue, e uma coluna discriminadora é usado para distingui-los na tabela de um:

<discriminator type="string">
    <column name="RESOURCE_TYPE" length="20" index="XIE1CPD_RESOURCE_BUNDLE_L_V"/>
</discriminator>
...
<subclass name="StandardResourceBundleValue" discriminator-value="STANDARD">
    <property name="messageValue" type="string" column="STD_MSG_VALUE" length="400"/>
</subclass>
<subclass name="LargeResourceBundleValue" discriminator-value="LARGE">
    <property name="messageValue" type="materialized_clob" column="LARGE_MSG_VALUE"/>
</subclass>

Aqui está a parte divertida: Se o valor de uma chave começou pequeno (e persistiu como um StandardResourceBundleValue), então o valor é alterado para um maior que o VARCHAR, precisamos de uma maneira para convertê-lo a um StandardResourceBundleValue. O código que isso está acontecendo em não pode simplesmente excluir o StandardResourceBundleValue e criar um LargeResourceBundleValue, porque é isso que causa violações de restrição.

O que gostaríamos de fazer é definir uma propriedade para essa coluna discriminador, de modo a classe base pode ter um método que as mudanças que o valor no objeto, de modo que quando é persistiu novamente ele vai salvar o valor no CLOB.

<property name="resourceType" type="string">
    <column name="RESOURCE_TYPE"/>
</property>    

Quando eu tentar construir a tabela, eu recebo o seguinte erro:

repetida coluna no mapeamento de entidade: coluna com.foo.resourcebundle.LargeResourceBundleValue: RESOURCE_TYPE (devem ser mapeados com a inserção = "false" update = "false")

É claro que não entende o que eu estou tentando fazer, mas faz sentido que deve haver uma maneira de fazê-lo. Assim como você expor um campo discriminador como uma propriedade?

Graças.

Foi útil?

Solução

Você não pode fazer isso. Um objeto tem um tipo, e não pode mudar de um tipo para outro. Isso é apenas como Java funciona.

Eu acho que você simplesmente não deve ter dois tipos de entidades aqui. Por que você não apenas armazenar o discriminador como uma coluna básica enum, e armazenar / buscar o valor da propriedade na coluna varchar ou clob com base no valor desta enumeração. Certifique-se de tudo é transparente encapsulado no objeto, e tudo será mais fácil, mesmo para os chamadores. O campo enum pode até não ser tornada pública. Você usá-lo para implementar getMessageValue() (obter o valor da coluna for o caso), e você alterar seu valor quando setMessageValue() é chamado, com base no comprimento do novo valor.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top