Hibernate JoinTable error: Unable to find column with logical name - java

I am trying to do a Unidirectional ManyToOne association via a JoinTable in hibernate, but I keep getting the following error:
A JPA error occurred (Unable to build EntityManagerFactory): Unable to find column with logical name: name in org.hibernate.mapping.Table(users) and its related supertables and secondary tables
I have 3 models House, User, UserHouseMap. I want to be able to access a users house through the UserHouseMap. Here is the mapping on the User
For other reasons, I need to map a User to UserHouseMap via a column that is not a primary key
#Id
#GeneratedValue
#Expose
public Long id;
#Expose
#Required
#ManyToOne
#JoinTable(name = "user_house_map",
joinColumns= {#JoinColumn(table="users", name="user_name", referencedColumnName="name")},
inverseJoinColumns={#JoinColumn(table="houses", name="house_name", referencedColumnName="house_name")})
public House house;
Here are the DB schemas for all 3 models
Users
Table "public.users"
Column | Type | Modifiers
-----------------------+-----------------------------+-----------------------------
name | character varying(255) |
id | integer | not null
Indexes:
"user_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"housing_fkey" FOREIGN KEY (name) REFERENCES user_house_map(user_name) DEFERRABLE INITIALLY DEFERRED
Houses
Table "public.houses"
Column | Type | Modifiers
---------------+------------------------+-----------
house_name | character varying(255) | not null
address | text |
city | text |
state | text |
zip | integer |
zip_ext | integer |
phone | text |
Indexes:
"house_pkey" PRIMARY KEY, btree (house_name)
Referenced by:
TABLE "user_house_map" CONSTRAINT "house_map_fkey" FOREIGN KEY (house_name) REFERENCES house(house_name) DEFERRABLE INITIALLY DEFERRED
UserHouseMap
Table "public.user_house_map"
Column | Type | Modifiers
-------------+------------------------+-----------
user_name | character varying(255) | not null
house_name | character varying(255) | not null
Indexes:
"user_house_map_pkey" PRIMARY KEY, btree (user_name)
"user_house_map_house_key" btree (house_name)
Foreign-key constraints:
"user_house_map_house_fkey" FOREIGN KEY (house_name) REFERENCES houses(house_name) DEFERRABLE INITIALLY DEFERRED
Referenced by:
TABLE "users" CONSTRAINT "housing_fkey" FOREIGN KEY (name) REFERENCES user_house_map(user_name) DEFERRABLE INITIALLY DEFERRED

Remove table="users" and table="houses" from the JoinColumn annotations.
This attribute should not contain the target table of the foreign key. It's only used when an entity is mapped to two tables, in order to tell which table the join column is in.
Also, your table definitions are quite strange:
the join table should have two foreign keys: one referencing the PK of the users table, and one referencing the PK of the house table. Why do you reference the name of a user rather than its ID?
the foreign key constraint on users.name doesn't make sense.

Related

Remove zombie foreign keys in MYSQL

I'm trying to build a MySQL database gradually, by generation using JPA and Eclipse-Link. Along the way, I've changed some relationships #ManyToOne, #OneToOne etc.
I now have a situation where I have some spurious foreign keys: the tables don't exist, but the referenced tables still do. I think the original tables were cross-reference tables generated by EclipseLink but are no longer around.
The issue is, I cannot delete these referenced tables. I get an error like this:
mysql> drop table PRODUCTDO;
ERROR 3730 (HY000): Cannot drop table 'PRODUCTDO' referenced by a foreign key constraint 'PRODUCTDO_DISTRIBUTIONCENTERPRODUCTDO_ProductDo_ID' on table 'PRODUCTDO_DISTRIBUTIONCENTERPRODUCTDO'.
If I run:
SET foreign_key_checks = 0;
then I can delete the table, but the constraint still remains. Even if I drop the database and create it again, the constraint is still there:
mysql> SELECT TABLE_NAME,COLUMN_NAME,CONSTRAINT_NAME, REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE REFERENCED_TABLE_SCHEMA = 'SCO';
+---------------------------------------+------------------------------+----------------------------------------------------+-----------------------------+------------------------+
| TABLE_NAME | COLUMN_NAME | CONSTRAINT_NAME | REFERENCED_TABLE_NAME | REFERENCED_COLUMN_NAME |
+---------------------------------------+------------------------------+----------------------------------------------------+-----------------------------+------------------------+
| PRODUCTDO_DISTRIBUTIONCENTERPRODUCTDO | ProductDo_ID | PRODUCTDO_DISTRIBUTIONCENTERPRODUCTDO_ProductDo_ID | PRODUCTDO | ID |
| PRODUCTDO_DISTRIBUTIONCENTERPRODUCTDO | distributionCenterProduct_ID | PRDCTDDSTRBTIONCENTERPRODUCTDOdstrbtnCntrProductID | DISTRIBUTIONCENTERPRODUCTDO | ID |
+---------------------------------------+------------------------------+----------------------------------------------------+-----------------------------+------------------------+
2 rows in set (0.01 sec)
How can I get rid of these zombie constraints?
In the end, I had to recreate the table and foreign key then I was able to delete it.

create table with #ManyToMany and #ManyToOne relation

I'm struggling with creating tables with #ManyToMany and #ManyToOne relations.
I have to create 3 tables, person, country, gender.
Person and country relationship #ManyToMany and person, gender #ManyToOne.
Is my code correct?
CREATE TABLE IF NOT EXISTS `di_person` (
`id_person` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(256) ,
`last_name` VARCHAR(256) ,
`additional_info` VARCHAR(256) ,
`gender_id` VARCHAR (50) UNIQUE REFERENCES di_gender,
`country_id` VARCHAR (50) UNIQUE REFERENCES di_country
) COLLATE='utf8_bin';
-- -----------------------------------------------------
-- Table 'gender`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `di_gender` (
id_gender INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
id_person INT,
name VARCHAR(50),
CONSTRAINT tb_fk FOREIGN KEY (id_person) REFERENCES di_person(id_person)
) COLLATE='utf8_bin';
-- -----------------------------------------------------
-- Table 'country`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `di_country` (
`id_country` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` VARCHAR(256),
`id_person` VARCHAR (10) UNIQUE REFERENCES di_person
) COLLATE='utf8_bin';
I would have said not. Person is unique and should only have one entry per person. I suggest that the gender should remain in person and have a foreign key reference for validation purposes (i don't like enums), but am a bit dubious about holding country in the person table (more of this later). Gender should not have the person id and neither should country -otherwise duplicates of gender and country would exist. Not knowing what your data looks like i might create a person_country junction table so that a person can be associated with more than one country if that will never be the case then holding the country code in person (with a foreign key constraint) would be fine.

JPA/Hibernate - Use unique constraint as primary key

I have the following problem, I have a already existing table with three fields field1, field2, field3. Field1 is actually a foreign key (#OneToOne) to another table. All field2 and field3 can be null, so I can't set a primary key for all three fields. In the database there is a UniqueConstraint for field1+field2+field3.
field1 | field2 | field 3
1 | 1 | null
1 | null | 2
3 | 1 | null
I've tried several solutions with JPA/Hibernate but could not find a good one.
Without defining a #Id JPA can not work (of course). Defining the three fields in a #Embeddable and reuse it with #EmbeddedId creates a primary key over all three fields which do not allow null values.
Is there any other solution than change the existing table and add a auto generated id for each row?
Thank you so much & best regards!
Have you tried as below?
#Table(
name="xxx",
uniqueConstraints=
#UniqueConstraint(name="my_unique_key", columnNames={"field1", "field2", "field3"})
)

Hibernate Mapping One-to-many in one table

We have the following (poorly designed?) table:
inputs:
keyword_id serial not null,
group_name string not null,
banned_term string not null
Keyword ID is the primary key. there are many banned terms per group_name. The data looks like this:
keyword_id | group_name | banned_term
1 | incentivization | free money
2 | inaccuracy | we're number one
3 | incentivization | win a free ipod!
There's no join table, and group_name isn't its own entity. I'd like a domain object something like this:
class BannedTermGroup {
Integer id;
String group_name;
Set<String> banned_terms;
// ... various getters and setters
}
The only examples on this one-to-many relationship between the group name and banned terms all involve some sort of join column or join table, while group_name would always be part of some other entity. Here neither is the case. Can this be mapped using Hibernate?
As quoted in my previous comment, you can get the ID of the group from nowhere.
Just to put aside this problem, you may look into Hibernate's reference, search for collections of basic types. It is what you need.
However, you still need to have a table for the "group".
assume it is as simple as a one column table:
KEYWORD_GROUP
--------------------
GROUP_NAME STRING
Your original keyword table:
KEYWORD
--------------------
GROUP_NAME STRING
KEYWORD STRING
I believe this is what you need:
#Entity
#Table("KEYWORD_GROUP")
public class KeywordGroup {
[.....]
#ElementCollection
#CollectionTable(name="KEYWORD", joinColumns=#JoinColumn(name="GROUP_NAME"))
#Column(name="KEYWORD")
private List<String> keywords;
}
For the keyword_group table, you probably don't need to create a new table if you are just using this model for read. Create a view from your original keyword table should be good enough.

Nullable Foreign Key Constraints

We are trying increase the scope of database compatibility for our web application. Our application is Java EE with JSPs, Servlets, and EJBs. The database we are trying to make our application compatible with is SQL Server 2008.
The problem we are running into is that our application uses nullable foreign keys in many cases in many files. These nullable foreign keys work in other databases but we have not found a way to get them to work in SQL Server 2008 because it will only allow a single foreign key to be 'null' at a given time. We understand that, in general, it is best to avoid such nullable foreign keys. However, this web application is large and it would be quite difficult to change files one-by-one.
Thus far, we have tried the following:
[1] initializing dummy elements in referenced tables so that the foreign keys will point to something.
[2] using 'EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"' in order to remove the foreign key constraint
Unfortunately, initializing dummy elements in [1] above broke many components in the web application.
Unfortunately, trying to remove the constraint according to the statement in [2] above did not work. We suspect this because subsequent attempts to drop each table result in Foreign Key constraint errors.
Currently, clear answers to the following questions would help us make some progress:
[1] Is there a quick fix to allow SQL Server 2008 to allow for multiple 'null'-valued foreign keys?
[2] Is there another workaround we could try that would not involve extensive changes to our web application?
I'm not sure what you are talking about! Possibly if you posted a sample schema, I could understand what you mean.
You can have multiple null FK columns in a table:
build the tables and FKs:
CREATE TABLE dbo.AAAA
(
A_ID int NOT NULL identity(1,1) primary key,
B_ID int NULL,
C_ID int NULL
) ON [PRIMARY]
CREATE TABLE dbo.BBBB
(
B_ID int NOT NULL identity(1,1) primary key,
A_ID int NULL,
C_ID int NULL
) ON [PRIMARY]
CREATE TABLE dbo.CCCC
(
C_ID int NOT NULL identity(1,1) primary key,
A_ID int NULL,
B_ID int NULL
) ON [PRIMARY]
ALTER TABLE dbo.CCCC ADD CONSTRAINT FK_CCCC_AAAA FOREIGN KEY ( A_ID ) REFERENCES dbo.AAAA ( A_ID ) ON UPDATE NO ACTION ON DELETE NO ACTION
ALTER TABLE dbo.BBBB ADD CONSTRAINT FK_BBBB_AAAA FOREIGN KEY ( A_ID ) REFERENCES dbo.AAAA ( A_ID ) ON UPDATE NO ACTION ON DELETE NO ACTION
ALTER TABLE dbo.CCCC ADD CONSTRAINT FK_CCCC_BBBB FOREIGN KEY ( B_ID ) REFERENCES dbo.BBBB ( B_ID ) ON UPDATE NO ACTION ON DELETE NO ACTION
ALTER TABLE dbo.AAAA ADD CONSTRAINT FK_AAAA_BBBB FOREIGN KEY ( B_ID ) REFERENCES dbo.BBBB ( B_ID ) ON UPDATE NO ACTION ON DELETE NO ACTION
ALTER TABLE dbo.AAAA ADD CONSTRAINT FK_AAAA_CCCC FOREIGN KEY ( C_ID ) REFERENCES dbo.CCCC ( C_ID ) ON UPDATE NO ACTION ON DELETE NO ACTION
ALTER TABLE dbo.BBBB ADD CONSTRAINT FK_BBBB_CCCC FOREIGN KEY ( C_ID ) REFERENCES dbo.CCCC ( C_ID ) ON UPDATE NO ACTION ON DELETE NO ACTION
insert sample data:
INSERT INTO AAAA VALUES (NULL,NULL)
INSERT INTO AAAA VALUES (NULL,NULL)
INSERT INTO AAAA VALUES (NULL,NULL)
INSERT INTO BBBB VALUES (1,NULL)
INSERT INTO BBBB VALUES (2,NULL)
INSERT INTO BBBB VALUES (NULL,NULL)
INSERT INTO BBBB VALUES (NULL,NULL)
INSERT INTO BBBB VALUES (1,NULL)
Show the data (see how many FK columns are null):
select * from AAAA
select * from BBBB
select * from CCCC
OUTPUT:
A_ID B_ID C_ID
----------- ----------- -----------
1 NULL NULL
2 NULL NULL
3 NULL NULL
(3 row(s) affected)
B_ID A_ID C_ID
----------- ----------- -----------
1 1 NULL
2 2 NULL
3 NULL NULL
4 NULL NULL
5 1 NULL
(5 row(s) affected)
C_ID A_ID B_ID
----------- ----------- -----------
(0 row(s) affected)
If this isn't what you are talking about, you need to provide some sample tables and data.
remove these test tables:
ALTER TABLE dbo.CCCC drop CONSTRAINT FK_CCCC_AAAA
ALTER TABLE dbo.BBBB drop CONSTRAINT FK_BBBB_AAAA
ALTER TABLE dbo.CCCC drop CONSTRAINT FK_CCCC_BBBB
ALTER TABLE dbo.AAAA drop CONSTRAINT FK_AAAA_BBBB
ALTER TABLE dbo.AAAA drop CONSTRAINT FK_AAAA_CCCC
ALTER TABLE dbo.BBBB drop CONSTRAINT FK_BBBB_CCCC
drop table AAAA
drop table BBBB
drop table CCCC

Categories