0

I'm trying to create a class with a foreign composite key and everything works fine, except that the DDL generation doesn't create indeces as expected.

I will explain better with some code; the part of the code I'm trying to implement is the ribbon awarding: a User can have many Ribbons and a Ribbon can have many Users (many-to-many).

Ribbon class:

@Entity
@Table(name = "ribbon")
public class Ribbon
{
    @AttributeOverrides({
            @AttributeOverride(
                    name = "id",
                    column = @Column(name = "id", nullable = false, length = 4)
            ),
            @AttributeOverride(
                    name = "level",
                    column = @Column(name = "level", nullable = false)
            )
    })
    @EmbeddedId
    RibbonId id;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "ribbon")
    private Set<UserHasRibbon> userHasRibbonSet;

    // ...
}

RibbonId class:

@Embeddable
public class RibbonId implements Serializable
{
    public int id;

    @Enumerated(EnumType.STRING)
    public UserLevel level;

    @Override
    public boolean equals(Object o)
    {
        // ...
    }

    @Override
    public int hashCode()
    {
        // ...
    }
}

UserHasRibbon class:

@Entity
@Table(name = "user_has_ribbon")
public class UserHasRibbon
{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id", nullable = false, length = 16)
    private int id;

    @ManyToOne(optional = false)
    @JoinColumn(name = "user_id", nullable = false)
    private User user;

    @ManyToOne(optional = false)
    @JoinColumns({
            @JoinColumn(name="ribbon_id", referencedColumnName="id", nullable = false),
            @JoinColumn(name="ribbon_level", referencedColumnName="level", nullable = false)
    })
    private Ribbon ribbon;

    @Column(name = "earned_date", nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date earnedDate;

    // ...
}

It's pretty straightforward and everything is working perfectly. The only problem is that I noticed that the automatic DDL generation didn't create the indeces in the user_has_ribbon table:

  • ribbon_id has an index but is not linked to ribbon.id
  • ribbon_level doesn't have an index at all
  • user_id is correct, has an index linked to user.id

I know that the DDL generation should be disabled for production, I'm just wondering why it's not behaving as expected.

Thank you!

satoshi
  • 3,963
  • 6
  • 46
  • 57
  • How it is behaving depends on which JPA implementation you are using. A thing to consider is why you are wondering this - of course it is good to tinker - but in this case I'm pretty sure you should be tinkering with(in) the JPA implementation. – esej May 20 '12 at 17:48
  • Thank you for your answer, @esej. The JPA implementation is Hibernate and the database is MySQL. I found the "solution", see my own answer to my question. Silly me... Thanks! – satoshi May 20 '12 at 18:24
  • Cool, please accept your own answer. (So people looking for questions to answer doesn't find this one.) – esej May 20 '12 at 18:31
  • I know, but I have to wait 2 days to accept it.. :) – satoshi May 20 '12 at 19:06

1 Answers1

1

I just realized that JPA did create a composite index on the two columns (ribbon_id and ribbon_level) and it's working fine. I got confused because phpMyAdmin doesn't show relations correctly when it's about composite indeces...

satoshi
  • 3,963
  • 6
  • 46
  • 57