@OneToOne mit nullable Column

Sk70

Mitglied
Ich habe eine Klasse,

Beschreibung

Code:
@Entity
@Table(
        name="textblocks",
        uniqueConstraints = {@UniqueConstraint(columnNames = {"owner_id", "company_id"})}
)
public class Textblock {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)   
    private Integer             id;
   
    @CreationTimestamp
    private Date                created_at;
   
    @UpdateTimestamp
    private Date                updated_at;
   
    private Integer                owner_id;

    @OneToOne(cascade = CascadeType.REMOVE)
    private Company                company;
   
    @OneToOne(cascade = CascadeType.REMOVE)
    @Column(nullable = true)
    private TextblockCategory    category;
   
    private Boolean                published;
   
    private Integer                ordering;   
   
    private String                name;
   
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch=FetchType.EAGER)
    @JoinTable(
            name = "textblock_textes",
            joinColumns={ @JoinColumn(name="textblock_id", referencedColumnName="id") },
            inverseJoinColumns={ @JoinColumn(name="text_id", referencedColumnName="id", unique=true) }
   )
    @Fetch(value = FetchMode.SUBSELECT)
    private List<Text> textes = new ArrayList<Text>();
   
    /**
     * default constructor
     *
     * @return void
     */
    public Textblock() {
        super();
    }
   
    /**
     * initialize constructor
     *
     * @param Integer own_id                    the company specified ID
     * @param Company company                    the company owner of this field
     * @param TextblockCategory category        the associated category
     * @param Boolean published                    if Language available
     * @param Integer ordering                    the ordering of the field within a category
     * @param String name                        the name of the Textblock
     * @param List<Text> textes                    the text of this textblock
     * @return void
     */
    public Textblock(Integer owner_id, Company company, TextblockCategory category, Boolean published, Integer ordering,
            String name, List<Text> textes) {
        super();
        this.owner_id = owner_id;
        this.company = company;
        this.category = category;
        this.published = published;
        this.ordering = ordering;
        this.name = name;
        this.textes = textes;
    }

    public Integer getId() {
        return id;
    }


    public void setId(Integer id) {
        this.id = id;
    }

    public Date getCreatedAt() {
        return created_at;
    }

    public Date getUpdatedAt() {
        return updated_at;
    }

    public Integer getOwnerId() {
        return owner_id;
    }

    public void setOwnerId(Integer owner_id) {
        this.owner_id = owner_id;
    }

    public Company getCompany() {
        return company;
    }

    public void setCompany(Company company) {
        this.company = company;
    }

    public Boolean getPublished() {
        return published;
    }

    public void setPublished(Boolean published) {
        this.published = published;
    }

    public Integer getOrdering() {
        return ordering;
    }

    public void setOrdering(Integer ordering) {
        this.ordering = ordering;
    }

    public TextblockCategory getCategory() {
        return category;
    }

    public void setCategory(TextblockCategory category) {
        this.category = category;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
   
    public List<Text> getTextes() {
        return textes;
    }

    public void setTextes(List<Text> textes) {
        this.textes = textes;
    }

    @Override
    public String toString() {
        return "Textblock [id=" + id + ", created_at=" + created_at + ", updated_at=" + updated_at + ", own_id="
                + owner_id + ", company=" + company + ", category=" + category + ", published=" + published
                + ", ordering=" + ordering + ", name=" + name + ", textes=" /*+ textes*/ + "]";
    }

}

Zusätzlich habe ich eine Klasse TextblockCategory um Textblöcke zu kategorisieren. Die Tabelle "textblocks" verfügt über eine Feld category_id um eine TextblockCategory entsprechend aufzunehmen.

Textblöcke müssen aber nicht zwangsläufig über eine Category verfügen. Sie können auch null sein - also eine unidirektionale 1 -> 0,1 Beziehung.

Darüber hinaus soll wenn TextblockCategory gelöscht wird per Cascade das Feld "category_id" der Tabelle "textblocks" auf null gesetzt werden.

Problem
Bei der Verwendung von

Code:
@OneToOne(cascade = CascadeType.REMOVE)
@Column(nullable = true)

Erhalte ich eine Fehlermeldung
@Column(s) not allowed on a @OneToOne

Lösung
????
 

Sk70

Mitglied
Naja, Lösung: weglassen oder @JoinColumn verwenden.
Danke erstmal. Ich verstehe es jetzt nur noch nicht so ganz was du damit meinst.
Wenn ich @Column weglasse wie sage ich es ihm dann das diese Verbindung alternativ null sein kann. @JoinColumn gibt doch nur an wie gejoint wird???? :confused:

Moin,


Was sind denn das für Einträge? Das ist doch kein Java, oder?? :confused:

VG Klaus
Und wenn du wissen willst was die Annotations in meinem Code-Schnippsel aussagen. Das findest du hier https://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/
 
Zuletzt bearbeitet:

Sk70

Mitglied
Und wofür glaubst Du, dass category_id da ist?


Standardmäßig dürfte nullable == true sein.

category_id ist dazu da um hibernate mitzuteilen, wie dier Spaltenname heist auf dem der Join beruht.

Es ist standardmässig nicht null. Wenn ich die Nullable @Column weglasse erhalte ich eine Bezugsverletztung von H2 (läuft zur Zeit zum Testen auf H2) wenn ich versuche via INSERT eine nullabled 'category' Textblock zu erstellen.
 

Sk70

Mitglied
Ja da ja auf H2 wird bei jedem neuen Run der Process vorher von mir beendet und die Tabellen werden mittels Hibernate und Spring Data data.sql (nur Insert - SQL) neu erstellt.
 

mihe7

Top Contributor
category_id ist dazu da um hibernate mitzuteilen, wie dier Spaltenname heist auf dem der Join beruht.
Daher JoinColumn.

Ich verstehe zwar nicht, warum bei Dir nullable false sein sollte aber dann mach halt um Himmelswillen ein
Code:
@JoinColumn(nullable=true)
rein.
 

JuKu

Top Contributor
Danke erstmal. Ich verstehe es jetzt nur noch nicht so ganz was du damit meinst.
Wenn ich @Column weglasse wie sage ich es ihm dann das diese Verbindung alternativ null sein kann. @JoinColumn gibt doch nur an wie gejoint wird???? :confused:

Du joinst ja im Grunde genommen auch, da es eine Relation ist!
Bei Relationen (OneToOne, ManyToOne, OneToMany usw.) ist die Annotation @Column nie erlaubt, dafür gibt es den "Ersatz" @JoinColumn. Ich muss aber ehrlich zugeben, dass es für Anfänger etwas missverständlich ist.

Übrigens:
Wenn du den fetch-Type nicht auf LAZY setzt, lädt JPA / Hibernate die Daten auch automatisch (z.B. per JOIN) nach.
 

Ähnliche Java Themen

Neue Themen


Oben