2017-02-27 2 views
1

Ich habe eine KlasseHibernate: Zusätzliche Anmerkung zur Spalte von Vererbung

@MappedSuperclass 
public abstract class MyAbstractProperty <T extends Object>{ 

    @Id 
    @GeneratedValue(strategy = GenerationType.TABLE) 
    private Long id; 

    @Column(name="defaultValue") 
    protected T defaultValue; 

//... 

} 

Welche Grundlage für die Unterklassen wie class MyLongProperty extends MyAbstractProperty<Long>{} ist. Das funktioniert gut. Das Problem tritt auf, wenn ich Text in der Klasse class MyStringProperty extends MyAbstractProperty<String>{} speichern möchte.

Ich habe gelernt, dass Hibernate standardmäßig speichert Strings nur mit max 255 Zeichen (siehe: JPA: "Data too long for column" does not change). Daher müsste meine defaultValue eine zusätzliche Anmerkung wie:

@Entity 
class MyStringProperty extends MyAbstractProperty<String>{ 

    @Type(type="org.hibernate.type.StringClobType") 
    @Column(name="defaultValue") 
    protected String defaultValue; // problem since defaultValue is already defined in MyAbstractProperty<>. 
} 

Wie kann ich dies gewährleisten, da die Default bereits in MyAbstractProperty definiert ist? Ich denke nicht, dass es in Ordnung ist, den Typ Annotation zu MyAbstractProperty zu verschieben, da dies Nebenwirkungen auf andere Klassen wie MyLongProperty haben kann.

Zum Beispiel, als ich @Lob in MyAbstractProperty die SQL-Definition MyStringProperty Einstellung enthalten DEFAULTVALUE BLOB(255) statt DEFAULTVALUE BIGINT.

Zusätzliche Frage: Es scheint verschiedene Optionen zum Definieren der Spalte als Textdaten (z. B. @Type(type="org.hibernate.type.StringClobType"), @Lob) Wo sind die wichtigsten Unterschiede in diesen Optionen. Was am besten zu nehmen. (Meine Hauptdatenbank ist HyperSQL, aber ich ziele auch auf SQLite, MariaDB und MySQL).

bearbeiten

Basierend auf der jüngsten Feedback scheint es, wie die Lösung abstrakte Getter/Setter sein könnte. Ich muss prüfen, welche Auswirkungen dies auf meinen Code hat.

Ich hatte eine Alternative - nicht abgeschlossen - Idee, die weniger Modifikationen meines Codes verursachen könnte. Ist es möglich, eine Klasse

class MyText extendes String; 

wie, dass alle Instanzen von MyText werden automatisch als @Lob gespeichert zu definieren? Dann müsste ich nur MyAbstractProperty<String> zu MyAbstractProperty<MyText> ändern.

+0

ich denke, dass Sie einer der Vererbungsstrategien folgen müssen, lesen Sie diesen Artikel also bitte http://www.thejavadeek.com/2014/ 05/14/jpa-single-table-vererbung-beispiel/ –

+0

Also müssen Sie in der Regel die @Inheritance-Annotation mit der gewünschten Strategie in der abstrakten Klasse –

+0

verwenden. Außerdem sollten Sie defaultValue aus MyStringProperty entfernen, da es sich bereits in der Superklasse befindet und @Type (type = "org.hibernate.type .StringClobType ") zu MyAbstractProperty –

Antwort

1

Sie konnten lassen nur eine abstrakte Getter in der übergeordneten Klasse und definieren das Feld in Unterklassen:

@MappedSuperclass 
public abstract class MyAbstractProperty<T extends Object>{ 

    @Id 
    @GeneratedValue(strategy = GenerationType.TABLE) 
    private Long id; 

    public abstract T getDefaultValue(); 
} 

@Entity 
class MyStringProperty extends MyAbstractProperty<String>{ 

    @Type(type="org.hibernate.type.StringClobType") 
    @Column(name="defaultValue") 
    protected String defaultValue; 

    @Override 
    public String getDefaultValue() { 
     return defaultValue; 
    } 
} 

Um vorformulierten für alle anderen Fälle zu vermeiden, die eine besondere Behandlung nicht benötigen, können Sie einfach erstellen Eine weitere abstrakte Klasse, die die Standardzuordnung enthält und dann andere Entitäten daraus erweitert:

@MappedSuperclass 
public abstract class MyDefaultProperty<T> extends MyAbstractProperty<T extends Object> { 

    @Column(name="defaultValue") 
    protected T defaultValue; 

    @Override 
    public T getDefaultValue() { 
     return defaultValue; 
    } 
} 
+0

Vielen Dank Dragan Bozanovic für Ihre Antwort. Es scheint möglich zu sein, dass ein Refactoring in meinem Code erforderlich ist. Bitte überprüfen Sie auch die Bearbeitung meiner Frage. Vielleicht könnte diese Idee zu einer einfacheren Lösung führen? – BerndGit

+0

@BerndGit Sie können nicht von 'String' ausgehen, es ist eine letzte Klasse. Und selbst wenn Sie könnten, wäre der Effekt derselbe, da Sie die Annotation "@ Lob" auf das Feld des Typs "MyText" in der enthaltenen Klasse setzen müssten. –

Verwandte Themen