-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: Problems reverse engineering tables with composite FK
PostPosted: Tue Jul 21, 2015 4:52 am 
Newbie

Joined: Tue Jul 21, 2015 4:22 am
Posts: 1
Hello!

I try to reverse engineer my tables (PostgreSQL) which use composit keys for their PK and FK.
See a simple two tables example:

Code:
CREATE TABLE foo (
    id INTEGER NOT NULL,
    config INTEGER NOT NULL,
    foo_string CHARACTER VARYING(250),
    CONSTRAINT foo_pk PRIMARY KEY (id, config)
);

CREATE TABLE bar (
    id INTEGER NOT NULL,
    config INTEGER NOT NULL,
    foo_fid INTEGER NOT NULL,
    bar_string CHARACTER VARYING(250),
    CONSTRAINT bar_pk PRIMARY KEY (id, config),
    CONSTRAINT bar_fk FOREIGN KEY (foo_fid, config) REFERENCES foo (id, config)
);


If I reverse engineer my tables I get the following classes (truncated to only show the important parts):

Code:
@Entity
@Table(name = "foo")
public class Foo implements java.io.Serializable {
    private FooId id;
    private String fooString;
    private Set<Bar> bars = new HashSet<Bar>(0);

[...]

    @EmbeddedId
    @AttributeOverrides({
            @AttributeOverride(name = "id", column = @Column(name = "id", nullable = false)),
            @AttributeOverride(name = "config", column = @Column(name = "config", nullable = false)) })
    public FooId getId() {
        return this.id;
    }

[...]

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "foo")
    public Set<Bar> getBars() {
        return this.bars;
    }
}

@Entity
@Table(name = "bar")
public class Bar implements java.io.Serializable {

    private BarId id;
    private Foo foo;
    private String barString;

[...]

    @EmbeddedId
    @AttributeOverrides({
            @AttributeOverride(name = "id", column = @Column(name = "id", nullable = false)),
            @AttributeOverride(name = "config", column = @Column(name = "config", nullable = false)) })
    public BarId getId() {
        return this.id;
    }

[...]

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumns({
            @JoinColumn(name = "foo_fid", referencedColumnName = "id", nullable = false, insertable = false, updatable = false),
            @JoinColumn(name = "config", referencedColumnName = "config", nullable = false, insertable = false, updatable = false) })
    public Foo getFoo() {
        return this.foo;
    }

[...]
}


So far so good.
You can see that the Bar class is missing the foo_fid column. First I thought hibernate get this infomration out of the getFoo() method because the whole Foo-Object is stored in my Bar class.
But this is not the case.
Given the following test insert:

Code:
    int config = 1;
    Foo foo = new Foo(new FooId(815, config));
    foo.setFooString("This is my foo!");
    s.save(foo);
       
    Bar bar = new Bar(new BarId(4711, config), foo);
    bar.setBarString("This is my bar!");
    s.save(bar);
               
    s.getTransaction().commit();


results in the following error output:

Code:
    Hibernate: insert into foo (foo_string, config, id) values (?, ?, ?)
    Hibernate: insert into bar (bar_string, config, id) values (?, ?, ?)
    2015-07-21 10:38:12,988 [main] ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper {} - ERROR: null value in column "foo_fid" violates not-null constraint


As you can see hibernate is not inserting the foo_fid which results in the above error coming from the database itself.

If I manually adjust the Bar class by adding the missing fooFid field:

Code:
@Entity
@Table(name = "bar")
public class Bar implements java.io.Serializable {

    private BarId id;
    private Foo foo;
    private String barString;
    private int fooFid;

[...]

    @Column(name = "foo_fid", nullable = false)
    public int getFooFid() {
        return fooFid;
    }

    public void setFooFid(int fooFid) {
        this.fooFid = fooFid;
    }
}


and slightly adjust the insert example to the following:

Code:
    int config = 1;
    Foo foo = new Foo(new FooId(815, config));
    foo.setFooString("This is my foo!");
    s.save(foo);
       
    Bar bar = new Bar(new BarId(4711, config), foo);
    bar.setFooFid(foo.getId().getId());
    bar.setBarString("This is my bar!");
    s.save(bar);
               
    s.getTransaction().commit();


All is working fine.

I wonder if there is no way to reverse engineer such tables or if I do something terrible wrong here...

Appreciate any input for this.

Thanks
Martin


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.