Domanda

Abbiamo una tabella nel nostro sistema che memorizza le coppie chiave / valore della risorsa. Ci sono due colonne per memorizzare il valore; una colonna VARCHAR per valori più piccoli e un CLOB per valori più grandi. Sul lato Java, vengono istanziati in una delle due classi, StandardResourceBundleValue o LargeResourceBundleValue, e una colonna discriminatore viene utilizzata per distinguerli in una tabella:

<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>

Ecco la parte divertente: se il valore di una chiave è iniziato in piccolo (e persistito come StandardResourceBundleValue), il valore cambia in uno più grande di VARCHAR, abbiamo bisogno di un modo per convertirlo in StandardResourceBundleValue. Il codice in cui sta accadendo non può semplicemente eliminare StandardResourceBundleValue e creare un LargeResourceBundleValue, perché ciò causa violazioni dei vincoli.

Quello che vorremmo fare è definire una proprietà per quella colonna discriminatore, in modo che la classe base possa avere un metodo che cambia quel valore nell'oggetto, quindi quando viene persistito di nuovo salverà il valore nel CLOB.

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

Quando provo a creare la tabella, ottengo il seguente errore:

Colonna ripetuta nella mappatura per entità: Colonna com.foo.resourcebundle.LargeResourceBundleValue: RESOURCE_TYPE (dovrebbe essere mappato con insert="false" update="false")

Chiaramente non capisce cosa sto cercando di fare, ma ha senso che ci dovrebbe essere un modo per farlo. Quindi come esponi un campo discriminatore come proprietà?

Grazie.

È stato utile?

Soluzione

Non puoi farlo.Un oggetto ha un tipo e non può passare da un tipo all'altro.È così che funziona Java.

Penso che non dovresti avere due tipi di entità qui.Perché non si archivia il discriminatore come colonna enum di base e si archivia / recupera il valore della proprietà nella colonna varchar o clob in base al valore di questa enum.Assicurati che tutto sia incapsulato in modo trasparente nell'oggetto e tutto sarà più facile, anche per i chiamanti.Il campo enum potrebbe anche non essere reso pubblico.Lo usi per implementare getMessageValue() (ottieni il valore dalla colonna appropriata) e ne modifichi il valore quando viene chiamato setMessageValue(), in base alla lunghezza del nuovo valore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top