2017-06-16 49 views
1

我试图从LEGACY数据库模式构建jpa模型。JPA映射OneToMany与具有不同列名的组合键

我已经在mysql中创建了一个简单的数据库,并且我在eclipse(Reverse)中使用jpa工具生成了模型。

通过JPA工具生成的代码给出一个错误在我springboot项目:

org.springframework.beans.factory.BeanCreationException:错误创建名称为豆“的entityManagerFactory” 在类路径资源定义[组织/ springframework的/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]:

调用init方法失败;嵌套的例外是org.hibernate.AnnotationException:stackoverflow.entity.SecondTable.mainTable 的referencedColumnNames(ID)引用stackoverflow.entity.MainTable没有映射到一个单一的财产

我觉得很有道理,因为在我的SecondTable PK是( id,day),并且在MainTable中是(id,年,月,代码)。 现在,这个想法是有ID的相关。

几个环节: https://gigsterous.github.io/engineering/2016/09/25/spring-boot-2.html

对于属性倍率(也许指定列不相关) http://techqa.info/programming/question/33620473/hibernate-bidirectional-one-to-many-with-composite-key

JPA: Entity mapping with composite primary key and single key

这些是JPA工具创建的4个实体:

@Entity 
@Table(name="main_table") 
public class MainTable implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @EmbeddedId 
    private MainTablePK id; 

    private String comment; 

    //bi-directional many-to-one association to SecondTable 
    @OneToMany(mappedBy="mainTable") 
    private List<SecondTable> secondTables; 

    public MainTable() { 
    } 

} 

@Embeddable 
public class MainTablePK implements Serializable { 
    //default serial version id, required for serializable classes. 
    private static final long serialVersionUID = 1L; 

    private int id; 

    private String year; 

    private String month; 

    private String code; 

    public MainTablePK() { 
    } 
} 

@Entity 
@Table(name="second_table") 
public class SecondTable implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @EmbeddedId 
    private SecondTablePK id; 


    //bi-directional many-to-one association to MainTable 

    //I think I don’t need a bi-directional relationship, just from MainTable to SecondTable 

    //ERROR: NOT MAPPED TO A SINGLE PROPERTY 
    //I understand id in MainTable is a composite Key 
    @ManyToOne 
    @JoinColumn(name="id", referencedColumnName="id") 
    private MainTable mainTable; 


    public SecondTable() { 
    } 
} 


@Embeddable 
public class SecondTablePK implements Serializable { 
    //default serial version id, required for serializable classes. 
    private static final long serialVersionUID = 1L; 

    private int id; 

    private int day; 

    private int value1; 

    private int value2; 

    private int value3; 

    public SecondTablePK() { 
    } 
} 

SCRIPT SQL和示例数据列表

DROP TABLE IF EXISTS `main_table`; 
CREATE TABLE `main_table` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `year` char(4) NOT NULL, 
    `month` char(2) NOT NULL, 
    `code` char(6) NOT NULL, 
    `comment` varchar(45) DEFAULT NULL, 
    PRIMARY KEY (`id`,`year`,`month`,`code`) 
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; 

INSERT INTO `main_table` VALUES (1,'2017','01','333090','coment one'); 

This has a composite key 

DROP TABLE IF EXISTS `second_table`; 
CREATE TABLE `second_table` (
    `id` int(11) NOT NULL, 
    `day` int(11) NOT NULL, 
    `value1` int(11) DEFAULT NULL, 
    `value2` int(11) DEFAULT NULL, 
    `value3` int(11) DEFAULT NULL, 
    PRIMARY KEY (`id`,`day`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 


INSERT INTO `second_table` VALUES (1,0,1,NULL,NULL),(1,1,2,NULL,NULL),(1,2,NULL,NULL,NULL),(1,3,NULL,NULL,NULL),(1,4,NULL,NULL,NULL),(1,32,NULL,NULL,NULL); 

是否可以使用JPA实现? 有什么建议吗?

感谢

UPDATE

删除非PK场值1,值2,和值3,是一个错字。

遵循JPA 2.1规范,第2.4.1节中的示例2,第34,35页与我的非常相似。

因此应用:

@MapsId("empPK") 
       @JoinColumns({ 
@JoinColumn(name="FK1", referencedColumnName="firstName"), 
@JoinColumn(name="FK2", referencedColumnName="lastName") }) 

我们:做

@ManyToOne 
@MapsId("id") // maps the 'id' attribute of the embedded ID 
@JoinColumn(name="id", referencedColumnName="id") 
private MainTable mainTable; 

没有更多的变化。

我得到一个错误: org.springframework.beans.factory.BeanCreationException:错误创建名称为豆 '的entityManagerFactory' 在类路径资源定义[组织/ springframework的的/ boot /自动配置/ ORM/JPA/HibernateJpaAutoConfiguration.class] :调用init方法失败;嵌套异常是org.hibernate。AnnotationException:无法找到在@MapsId映射列引用:代码

如果我删除代码,相同的错误,但与,如果我删除一个月,同样的错误与

感谢

回答

0

首先,它出现在SecondTablePK是不正确的,因为它包括非PK场value1value2value3。这大概应该是这样的:

@Embeddable 
public class SecondTablePK implements Serializable { 
    //default serial version id, required for serializable classes. 
    private static final long serialVersionUID = 1L; 

    private int id; 

    private int day; 

    public SecondTablePK() { 
    } 
} 

至于共享id:通常情况下,相关的实体将引用父实体的整个主键,但您可能能够映射这样的关系:

@Entity 
@Table(name="second_table") 
public class SecondTable implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @EmbeddedId 
    private SecondTablePK id; 

    private int value1; 

    private int value2; 

    private int value3; 

    @ManyToOne 
    @MapsId("id") // maps the 'id' attribute of the embedded ID 
    @JoinColumn(name="id", referencedColumnName="id") 
    private MainTable mainTable; 


    public SecondTable() { 
    } 
} 

这很像一个“衍生的同一性”,这是在JPA 2.1规范讨论的,第2.4.1节。

+0

更新了我的问题,因为我用你的建议得到一个错误。 thxs – davisoski

+0

即闻起来有点像Hibernate期待''SecondTablePK以包括整个主键(即'私人MainTablePK mainTable'而不是“部分密钥”'私人INT id')。这是一个有点问题,你的外键包括'MainTable'的主键.... –

+0

嗯,看来这是不可能根据另一篇文章中有类似的东西,这样才*部分*:https://开头计算器.COM /问题/ 42245223/JPA的joincolumn一到多,双向关系上带有一个复合键,如,我还是谢谢你 – davisoski