Reputation: 847
I cannot seem to find a solution to this weird bug:
class Names(tag: Tag) extends Table[Name](tag, "NAME") with Identifiable[Name]{
def firstName = column[String]("firstName")
def lastName = column[String]("lastName")
def profileId = column[Int]("profileId")
def * = (id.?, firstName, lastName, profileId) <> ((Name.apply _).tupled, Name.unapply)
def profileFk = foreignKey("profile_fk", profileId, TableQuery[Profiles])(_.id, onDelete=ForeignKeyAction.Cascade)
}
class PhoneNumbers(tag: Tag) extends Table[PhoneNumber](tag, "PHONENUMBER") with Identifiable[PhoneNumber] {
def number = column[String]("number")
def kind = column[String]("kind")
def profileId = column[Int]("profileId")
def * = (id.?, number, kind, profileId) <> ((PhoneNumber.apply _).tupled, PhoneNumber.unapply)
def profileFk = foreignKey("profile_fk", profileId, TableQuery[Profiles])(_.id, onDelete=ForeignKeyAction.Cascade)
}
and the profile class consists of an id field only. Identifiable provides the id-property.
I am using Slick 3 with MySQL.
For Names a foreignKey to Profiles is generated, for PhoneNumbers not. Why? There seems to be no difference?
Update:
Here the relevant statements:
create table `PHONENUMBER` (`id` INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,`number` TEXT NOT NULL,`kind` TEXT NOT NULL,`profileId` INTEGER NOT NULL)
And:
alter table `PHONENUMBER` add constraint `profile_fk` foreign key(`profileId`) references `PROFILE`(`id`) on update NO ACTION on delete CASCADE
Complete Output:
create table PROFILE
(id
INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,userId
INTEGER NOT NULL)
create table VERSION
(id
INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,timestamp
INTEGER NOT NULL,vector
INTEGER NOT NULL)
create table NAME
(id
INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,firstName
TEXT NOT NULL,lastName
TEXT NOT NULL,profileId
INTEGER NOT NULL,versionId
INTEGER NOT NULL)
create table PHONENUMBER
(id
INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,number
TEXT NOT NULL,kind
TEXT NOT NULL,profileId
INTEGER NOT NULL,versionId
INTEGER NOT NULL)
create table VIEW
(id
INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY)
create table PHONENUMBERS_VIEWS
(phoneNumber
INTEGER NOT NULL,view
INTEGER NOT NULL)
create table CREDENTIALS
(id
INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,username
TEXT NOT NULL,password
TEXT NOT NULL,userId
INTEGER NOT NULL)
create table USER
(id
INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY)
create table API_KEY
(id
INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,token
TEXT NOT NULL,deviceId
TEXT NOT NULL,credentialsId
INTEGER NOT NULL)
alter table PROFILE
add constraint user_fk
foreign key(userId
) references USER
(id
) on update NO ACTION on delete NO ACTION
alter table NAME
add constraint profile_fk
foreign key(profileId
) references PROFILE
(id
) on update NO ACTION on delete CASCADE
alter table NAME
add constraint version_fk
foreign key(versionId
) references VERSION
(id
) on update NO ACTION on delete NO ACTION
alter table PHONENUMBER
add constraint profile_fk
foreign key(profileId
) references PROFILE
(id
) on update NO ACTION on delete CASCADE
alter table PHONENUMBER
add constraint version_fk
foreign key(versionId
) references VERSION
(id
) on update NO ACTION on delete NO ACTION
alter table PHONENUMBERS_VIEWS
add constraint phoneNumber_fk
foreign key(phoneNumber
) references PHONENUMBER
(id
) on update NO ACTION on delete NO ACTION
alter table PHONENUMBERS_VIEWS
add constraint view_fk
foreign key(view
) references VIEW
(id
) on update NO ACTION on delete NO ACTION
alter table CREDENTIALS
add constraint user_fk
foreign key(userId
) references USER
(id
) on update NO ACTION on delete NO ACTION
alter table API_KEY
add constraint credentials_fk
foreign key(credentialsId
) references CREDENTIALS
(id
) on update NO ACTION on delete NO ACTION
` symbol is hidden because of markdown, but there in the original output
EDIT 2:
val profiles = TableQuery[Profiles]
val names = TableQuery[Names]
val phoneNumbers = TableQuery[PhoneNumbers]
val views = TableQuery[Views]
val phoneNumbersToViews = TableQuery[PhoneNumbersToViews]
val users = TableQuery[Users]
val credentials = TableQuery[CredentialsSchema]
val apiKeys = TableQuery[ApiKeys]
val versions = TableQuery[Versions]
val schema = profiles.schema ++
versions.schema ++
names.schema ++
phoneNumbers.schema ++
views.schema ++
phoneNumbersToViews.schema ++
credentials.schema ++
users.schema ++
apiKeys.schema
SlickDB().run(DBIO.seq(
schema.create
))
schema.createStatements.foreach(println)
Upvotes: 1
Views: 770
Reputation: 4320
"For Names a foreignKey to Profiles is generated, for PhoneNumbers not. Why? There seems to be no difference?"
I think the lack of a difference is the problem here.
You've used the same foreign key name ("profile_fk") for Names.profileFk
and PhoneNumbers.profileFk
. The MySQL foreign key names need to be unique.
I'd suggest replacing "profile_fk" with "name_profile_fk" and "phonenumber_profile_fk".
However, you should be seeing an exception. The first of the alter table statements you included...
alter table NAME add constraint profile_fk foreign key(profileId) references PROFILE(id) on update NO ACTION on delete CASCADE
... should run OK, but the second...
alter table PHONENUMBER add constraint profile_fk foreign key(profileId) references PROFILE(id) on update NO ACTION on delete CASCADE
...is where there should be an exception.
If you're not seeing an exception, it could be that your application is terminating before the future you execute returns. You can test that out by placing an await around your SlickDB().run
command. E.g.,
import scala.concurrent.Await
import scala.concurrent.duration._
Await.result(
SlickDB().run(DBIO.seq(schema.create))
, 10 seconds)
Upvotes: 2