Spring Data Jpa - 复合主键问题
Spring Data Jpa - Composite primary key issue
我使用 play-spring-data-jpa 模板开始了一个项目,
我在尝试将休眠映射到使用复合主键的联接 table 时遇到了问题。
我要连接的数据库是一个现有的 mysql。
请看下面:
SQL:
CREATE TABLE IF NOT EXISTS `text_advertising`.`campaign_item_slots` (
`campaign_item_id` BIGINT NOT NULL,
`advert_slot_id` BIGINT NOT NULL,
`active` TINYINT(1) NOT NULL DEFAULT TRUE,
`date_created` DATETIME NOT NULL,
`date_updated` DATETIME NOT NULL,
PRIMARY KEY (`campaign_item_id`, `advert_slot_id`),
INDEX `fk_campaign_item_slots_2_idx` (`advert_slot_id` ASC),
CONSTRAINT `fk_campaign_item_slots_1`
FOREIGN KEY (`campaign_item_id`)
REFERENCES `text_advertising`.`campaign_items` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_campaign_item_slots_2`
FOREIGN KEY (`advert_slot_id`)
REFERENCES `text_advertising`.`advert_slots` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci;
CampaignItemSlot Class:
@Entity
@Table(name = "campaign_item_slots")
public class CampaignItemSlot implements Serializable{
@EmbeddedId
CampaignItemSlotId campaignItemSlotId;
private boolean active;
private Timestamp date_created;
private Timestamp date_updated;
}
CampaignItemSlotId Class
@Embeddable
public class CampaignItemSlotId implements Serializable{
@Column(name="advert_slot_id")
public long advertSlot;
@Column(name="campaign_item_id")
public long campaignItem;
}
当我设置 "hibernate.hbm2ddl.auto"、"validate" 时,出现以下错误:
Caused by: org.hibernate.HibernateException: Missing column: id in text_advertising.campaign_item_slots
当我设置 "hibernate.hbm2ddl.auto"、"update" 时,会在 campaign_item_slots table 中自动创建一个 id 字段,如我执行 show create table 时所示].这不是我想要的:
| campaign_item_slots | CREATE TABLE `campaign_item_slots` (
`campaign_item_id` bigint(20) NOT NULL,
`advert_slot_id` bigint(20) NOT NULL,
`active` tinyint(1) NOT NULL DEFAULT '1',
`date_created` datetime NOT NULL,
`date_updated` datetime NOT NULL,
`id` bigint(20) NOT NULL,
`advertSlot_id` bigint(20) DEFAULT NULL,
`campaignItem_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`campaign_item_id`,`advert_slot_id`),
KEY `fk_campaign_item_slots_2_idx` (`advert_slot_id`),
KEY `FK_q87o53119u79073jwttacsqta` (`advertSlot_id`),
KEY `FK_es60h5vj30rllkf0js1qy642y` (`campaignItem_id`),
CONSTRAINT `FK_es60h5vj30rllkf0js1qy642y` FOREIGN KEY (`campaignItem_id`) REFERENCES `campaign_items` (`id`),
CONSTRAINT `fk_campaign_item_slots_1` FOREIGN KEY (`campaign_item_id`) REFERENCES `campaign_items` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_campaign_item_slots_2` FOREIGN KEY (`advert_slot_id`) REFERENCES `advert_slots` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `FK_q87o53119u79073jwttacsqta` FOREIGN KEY (`advertSlot_id`) REFERENCES `advert_slots` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
这是我的 build.sbt:
version := "1.0-SNAPSHOT"
libraryDependencies ++= Seq(
javaCore,
javaJpa,
javaWs % "test",
"org.springframework" % "spring-context" % "4.1.4.RELEASE",
"org.springframework.data" % "spring-data-jpa" % "1.8.0.RELEASE",
"org.springframework" % "spring-orm" % "4.1.4.RELEASE",
"org.springframework" % "spring-jdbc" % "4.1.4.RELEASE",
"org.springframework" % "spring-tx" % "4.1.4.RELEASE",
"org.springframework" % "spring-expression" % "4.1.4.RELEASE",
"org.springframework" % "spring-aop" % "4.1.4.RELEASE",
"org.springframework" % "spring-test" % "4.1.4.RELEASE" % "test", javaJpa.exclude("org.hibernate.javax.persistence", "hibernate-jpa-2.0-api"),
"org.hibernate" % "hibernate-entitymanager" % "4.3.8.Final",
"javax.inject" % "javax.inject" % "1",
"mysql" % "mysql-connector-java" % "5.1.34",
"org.json" % "json" % "20090211"
)
lazy val root = (project in file(".")).enablePlugins(PlayJava)
我尝试了许多不同的使用 IdClass 和 EmbeddedId 等的组合,如本网站所述:mapping variations
因此,无论我尝试哪种组合,经过一些摆弄后,我都会遇到同样的错误:
Caused by: org.hibernate.HibernateException: Missing column: id in text_advertising.campaign_item_slots
我开始怀疑这是不是 spring 数据问题。
非常感谢对此的任何帮助。谢谢。
似乎下面的配置对我有用:
CampaignItemSlot.java
package models;
import java.io.Serializable;
import java.sql.Timestamp;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.ManyToOne;
import javax.persistence.MapsId;
import javax.persistence.Table;
@Entity
@Table(name = "campaign_item_slots")
public class CampaignItemSlot implements Serializable{
@EmbeddedId
private CampaignItemSlotPk campaignItemSlotPk;
@MapsId("advert_slot_id")
@JoinColumns({
@JoinColumn(name="advert_slot_id", referencedColumnName="id"),
})
@ManyToOne AdvertSlot advertSlot;
@MapsId("campaign_item_id")
@JoinColumns({
@JoinColumn(name="campaign_item_id", referencedColumnName="id"),
})
@ManyToOne CampaignItem campaignItem;
private boolean active;
private Timestamp date_created;
private Timestamp date_updated;
public CampaignItemSlot() {
super();
// TODO Auto-generated constructor stub
}
public CampaignItemSlotPk getCampaignItemSlotPk() {
return campaignItemSlotPk;
}
public void setCampaignItemSlotPk(CampaignItemSlotPk campaignItemSlotPk) {
this.campaignItemSlotPk = campaignItemSlotPk;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
public Timestamp getDate_created() {
return date_created;
}
public void setDate_created(Timestamp date_created) {
this.date_created = date_created;
}
public Timestamp getDate_updated() {
return date_updated;
}
public void setDate_updated(Timestamp date_updated) {
this.date_updated = date_updated;
}
public AdvertSlot getAdvertSlot() {
return advertSlot;
}
public void setAdvertSlot(AdvertSlot advertSlot) {
this.advertSlot = advertSlot;
}
public CampaignItem getCampaignItem() {
return campaignItem;
}
public void setCampaignItem(CampaignItem campaignItem) {
this.campaignItem = campaignItem;
}
}
CampaignItemSlotPK.java
package models;
import java.io.Serializable;
import java.sql.Timestamp;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Embeddable
public class CampaignItemSlotPk implements Serializable{
@Column(name="campaign_item_id")
private long campaignItem;
@Column(name="advert_slot_id")
private long advertSlot;
public CampaignItemSlotPk() {
// TODO Auto-generated constructor stub
}
public long getCampaignItem() {
return campaignItem;
}
public void setCampaignItem(long campaignItem) {
this.campaignItem = campaignItem;
}
public long getAdvertSlot() {
return advertSlot;
}
public void setAdvertSlot(long advertSlot) {
this.advertSlot = advertSlot;
}
}
build.sbt
javaJpa.exclude("org.hibernate.javax.persistence", "hibernate-jpa-2.0-api"),
"org.hibernate" % "hibernate-entitymanager" % "4.3.0.Final",
"mysql" % "mysql-connector-java" % "5.1.34",
这修复了它。
我使用 play-spring-data-jpa 模板开始了一个项目,
我在尝试将休眠映射到使用复合主键的联接 table 时遇到了问题。
我要连接的数据库是一个现有的 mysql。
请看下面:
SQL:
CREATE TABLE IF NOT EXISTS `text_advertising`.`campaign_item_slots` (
`campaign_item_id` BIGINT NOT NULL,
`advert_slot_id` BIGINT NOT NULL,
`active` TINYINT(1) NOT NULL DEFAULT TRUE,
`date_created` DATETIME NOT NULL,
`date_updated` DATETIME NOT NULL,
PRIMARY KEY (`campaign_item_id`, `advert_slot_id`),
INDEX `fk_campaign_item_slots_2_idx` (`advert_slot_id` ASC),
CONSTRAINT `fk_campaign_item_slots_1`
FOREIGN KEY (`campaign_item_id`)
REFERENCES `text_advertising`.`campaign_items` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_campaign_item_slots_2`
FOREIGN KEY (`advert_slot_id`)
REFERENCES `text_advertising`.`advert_slots` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci;
CampaignItemSlot Class:
@Entity
@Table(name = "campaign_item_slots")
public class CampaignItemSlot implements Serializable{
@EmbeddedId
CampaignItemSlotId campaignItemSlotId;
private boolean active;
private Timestamp date_created;
private Timestamp date_updated;
}
CampaignItemSlotId Class
@Embeddable
public class CampaignItemSlotId implements Serializable{
@Column(name="advert_slot_id")
public long advertSlot;
@Column(name="campaign_item_id")
public long campaignItem;
}
当我设置 "hibernate.hbm2ddl.auto"、"validate" 时,出现以下错误:
Caused by: org.hibernate.HibernateException: Missing column: id in text_advertising.campaign_item_slots
当我设置 "hibernate.hbm2ddl.auto"、"update" 时,会在 campaign_item_slots table 中自动创建一个 id 字段,如我执行 show create table 时所示].这不是我想要的:
| campaign_item_slots | CREATE TABLE `campaign_item_slots` (
`campaign_item_id` bigint(20) NOT NULL,
`advert_slot_id` bigint(20) NOT NULL,
`active` tinyint(1) NOT NULL DEFAULT '1',
`date_created` datetime NOT NULL,
`date_updated` datetime NOT NULL,
`id` bigint(20) NOT NULL,
`advertSlot_id` bigint(20) DEFAULT NULL,
`campaignItem_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`campaign_item_id`,`advert_slot_id`),
KEY `fk_campaign_item_slots_2_idx` (`advert_slot_id`),
KEY `FK_q87o53119u79073jwttacsqta` (`advertSlot_id`),
KEY `FK_es60h5vj30rllkf0js1qy642y` (`campaignItem_id`),
CONSTRAINT `FK_es60h5vj30rllkf0js1qy642y` FOREIGN KEY (`campaignItem_id`) REFERENCES `campaign_items` (`id`),
CONSTRAINT `fk_campaign_item_slots_1` FOREIGN KEY (`campaign_item_id`) REFERENCES `campaign_items` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_campaign_item_slots_2` FOREIGN KEY (`advert_slot_id`) REFERENCES `advert_slots` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `FK_q87o53119u79073jwttacsqta` FOREIGN KEY (`advertSlot_id`) REFERENCES `advert_slots` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
这是我的 build.sbt:
version := "1.0-SNAPSHOT"
libraryDependencies ++= Seq(
javaCore,
javaJpa,
javaWs % "test",
"org.springframework" % "spring-context" % "4.1.4.RELEASE",
"org.springframework.data" % "spring-data-jpa" % "1.8.0.RELEASE",
"org.springframework" % "spring-orm" % "4.1.4.RELEASE",
"org.springframework" % "spring-jdbc" % "4.1.4.RELEASE",
"org.springframework" % "spring-tx" % "4.1.4.RELEASE",
"org.springframework" % "spring-expression" % "4.1.4.RELEASE",
"org.springframework" % "spring-aop" % "4.1.4.RELEASE",
"org.springframework" % "spring-test" % "4.1.4.RELEASE" % "test", javaJpa.exclude("org.hibernate.javax.persistence", "hibernate-jpa-2.0-api"),
"org.hibernate" % "hibernate-entitymanager" % "4.3.8.Final",
"javax.inject" % "javax.inject" % "1",
"mysql" % "mysql-connector-java" % "5.1.34",
"org.json" % "json" % "20090211"
)
lazy val root = (project in file(".")).enablePlugins(PlayJava)
我尝试了许多不同的使用 IdClass 和 EmbeddedId 等的组合,如本网站所述:mapping variations
因此,无论我尝试哪种组合,经过一些摆弄后,我都会遇到同样的错误:
Caused by: org.hibernate.HibernateException: Missing column: id in text_advertising.campaign_item_slots
我开始怀疑这是不是 spring 数据问题。
非常感谢对此的任何帮助。谢谢。
似乎下面的配置对我有用:
CampaignItemSlot.java
package models;
import java.io.Serializable;
import java.sql.Timestamp;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.ManyToOne;
import javax.persistence.MapsId;
import javax.persistence.Table;
@Entity
@Table(name = "campaign_item_slots")
public class CampaignItemSlot implements Serializable{
@EmbeddedId
private CampaignItemSlotPk campaignItemSlotPk;
@MapsId("advert_slot_id")
@JoinColumns({
@JoinColumn(name="advert_slot_id", referencedColumnName="id"),
})
@ManyToOne AdvertSlot advertSlot;
@MapsId("campaign_item_id")
@JoinColumns({
@JoinColumn(name="campaign_item_id", referencedColumnName="id"),
})
@ManyToOne CampaignItem campaignItem;
private boolean active;
private Timestamp date_created;
private Timestamp date_updated;
public CampaignItemSlot() {
super();
// TODO Auto-generated constructor stub
}
public CampaignItemSlotPk getCampaignItemSlotPk() {
return campaignItemSlotPk;
}
public void setCampaignItemSlotPk(CampaignItemSlotPk campaignItemSlotPk) {
this.campaignItemSlotPk = campaignItemSlotPk;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
public Timestamp getDate_created() {
return date_created;
}
public void setDate_created(Timestamp date_created) {
this.date_created = date_created;
}
public Timestamp getDate_updated() {
return date_updated;
}
public void setDate_updated(Timestamp date_updated) {
this.date_updated = date_updated;
}
public AdvertSlot getAdvertSlot() {
return advertSlot;
}
public void setAdvertSlot(AdvertSlot advertSlot) {
this.advertSlot = advertSlot;
}
public CampaignItem getCampaignItem() {
return campaignItem;
}
public void setCampaignItem(CampaignItem campaignItem) {
this.campaignItem = campaignItem;
}
}
CampaignItemSlotPK.java
package models;
import java.io.Serializable;
import java.sql.Timestamp;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Embeddable
public class CampaignItemSlotPk implements Serializable{
@Column(name="campaign_item_id")
private long campaignItem;
@Column(name="advert_slot_id")
private long advertSlot;
public CampaignItemSlotPk() {
// TODO Auto-generated constructor stub
}
public long getCampaignItem() {
return campaignItem;
}
public void setCampaignItem(long campaignItem) {
this.campaignItem = campaignItem;
}
public long getAdvertSlot() {
return advertSlot;
}
public void setAdvertSlot(long advertSlot) {
this.advertSlot = advertSlot;
}
}
build.sbt
javaJpa.exclude("org.hibernate.javax.persistence", "hibernate-jpa-2.0-api"),
"org.hibernate" % "hibernate-entitymanager" % "4.3.0.Final",
"mysql" % "mysql-connector-java" % "5.1.34",
这修复了它。