如何使用JPA/Hibernate设置复合主键的列顺序

Gar*_*ett 3 mysql hibernate jpa composite-primary-key

我在复合主键中对列的排序有问题.我有一个包含以下内容的表:

@Embeddable
public class MessageInfo implements Serializable {

    private byte loc;
    private long epochtime;

    @Column(name = "loc")
    public byte getLoc() {
        return loc;
    }    

    @Column(name = "epochtime")
    public long getEpochtime() {
        return epochtime;
    }
}
Run Code Online (Sandbox Code Playgroud)

它用于此映射:

@MappedSuperclass
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class AbstractMessage implements Message {

    private MessageInfo info;
    private int blah;

    @EmbeddedId
    public MessageInfo getInfo() {
        return info;
    }
}
Run Code Online (Sandbox Code Playgroud)

当我用一个具体的@Table类继承AbstractMessage时,hibernate创建了没有错误的数据库和表.问题是hibernate生成复合主键,其列与我想要的顺序相反.

CREATE TABLE  `mydb`.`concrete_table` (
  `epochtime` bigint(20) NOT NULL,
  `loc` tinyint(4) NOT NULL,
  `blah` smallint(6) DEFAULT NULL,
  `foo` smallint(6) DEFAULT NULL,
  PRIMARY KEY (`epochtime`,`loc`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Run Code Online (Sandbox Code Playgroud)

我想要主键

PRIMARY KEY (`loc`,`epochtime`)
Run Code Online (Sandbox Code Playgroud)

因为我知道我将有最多10个loc,但每个loc的许多纪元.

任何帮助将不胜感激=)

Pau*_*nis 9

有办法做到这一点.休眠选择如何为主键排序一组列是按照您定义的对象名称的字母顺序排列的.

因此,例如,如果您声明您的对象如下:

private byte loc;
private long epochtime;
Run Code Online (Sandbox Code Playgroud)

你会得到你现在得到的:

(`epochtime`,`loc`)
Run Code Online (Sandbox Code Playgroud)

但如果你重命名它们,例如:

private byte aloc;
private long epochtime;
Run Code Online (Sandbox Code Playgroud)

它将生成为:

(`aloc`, `epochtime`)
Run Code Online (Sandbox Code Playgroud)

在e之前.

当我希望我的聚簇索引按特定顺序时,我发现了这一点.我知道这很烦人,但这是我能找到的唯一方法,所以我不必手动更改我的架构.

  • 我还有另一种体验,在主键中,“date”列在“company”之前。即使我让 Hibernate 重新生成整个数据库方案。 (2认同)

Jam*_* DW 0

我真的不认为有办法做到这一点。我所能做的就是建议您使用现有的 SQL 创建语句(将其更改为正确的顺序)并在生产中手动运行它。

在测试中让 Hibernate 做它的事情。