#OneToOne
private AnyEntity entity;
hibernate will create a mapping as follows:
CONSTRAINT fk_kcn86scsc0pasdasdngmrqc5i0 FOREIGN KEY (text_id)
REFERENCES some_table (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
Question: how can I set the constraint name explicit from within java?
I cannot introduce a bidirectional mapping, as the AnyEntity class will be used in multiple other #Entity classes.
You can use #ForeignKey annotation.
#ForeignKey(name="constraint_name")
Related
The JDO Inheritance guide for DataNucleus mentions that in InheritanceStrategy.NEW_TABLE class relationships, a foreign key will be created between the superclass' and subclass' tables. Running the DataNucleus schema generator, I do see that such a foreign key is being generated. What I can't discover, though, is how the names for these foreign keys can be customized.
For example:
#PersistenceCapable(table = "login_identities")
#Inheritance(strategy = InheritanceStrategy.NEW_TABLE)
public abstract class AbstractLoginIdentity { ... }
#PersistenceCapable(table = "email_login_identities")
#Inheritance(strategy = InheritanceStrategy.NEW_TABLE)
public class EmailLoginIdentity extends AbstractLoginIdentity { ... }
Given those classes, DataNucleus will generate a foreign key like the following (for PostgreSQL):
-- Constraints for table "email_login_identities" for class(es) [com.trickle.api.accounts.EmailLoginIdentity]
ALTER TABLE "email_login_identities" ADD CONSTRAINT "email_login_identities_FK1" FOREIGN KEY ("id") REFERENCES "login_identities" ("id") ;
I can't discover any way to alter the "email_login_identities_FK1" constraint's name. Adding a #ForeignKey annotation to the subclass just adds a new foreign key.
Can this be customized?
The foot of this page shows how to define a foreign key for the join to superclass, using XML.
I don't see a way of doing that in annotations (since #Inheritance has no #Join, and #Join has no #ForeignKey) ... but then I would never want to hardcode ORM definitions into a Java class. I assume you could request such a facility in annotations via the Apache JDO people.
I am using hibernate and Mysql in the java project for persistence.
I have two entities Transaction and Service. Transaction is having many to one relation to service.
I wanted to use a non primary column(SERVICE_CODE) of type VARCHAR from Service table as a foreign key in the Transaction table. But when I do so I get the following exception.
SQL Error: 1452, SQLState: 23000
Cannot add or update a child row: a foreign key constraint fails.
SERVICE_CODE is defined as non null and unique in database.
Following example works fine if I use primary key from Service table for mapping.
#Entity
#Table(name="Transaction")
public class Transaction {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="TRANSACTION_ID")
long transactionId;
#ManyToOne
#JoinColumn(name="SERVICE_CODE")
Service service;
}
#Entity
#Table(name="SERVICE")
public class Service {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="SERVICE_ID")
Long serviceId;
#Column(name="SERVICE_CODE")
String serviceCode;
}
As explained in this article, you should use the referencedColumnName attribute of the #JoinColumn annotation to specify the referenced column of the foreign key relationship.
#ManyToOne
#JoinColumn(name="SERVICE_CODE", referencedColumnName="SERVICE_CODE")
Service service;
With this modification the DDL is generated correctly like this:
alter table Transaction
add constraint FK_5k37nrtsvi22y2jhsde903ps9
foreign key (SERVICE_CODE)
references SERVICE (SERVICE_CODE);
and with your original code like this (it references primary key of the SERVICE table instead of the SERVICE_CODE column):
alter table Transaction
add constraint FK_5k37nrtsvi22y2jhsde903ps9
foreign key (SERVICE_CODE)
references SERVICE;
in JPA2 when we are using Embed-able (Basic Type like String.. etc ) object in Entity using with #ElementCollection and #CollectionTable annotation , the new table is created , but in new table how to declare primary-key contraint in column ? following is my code
public class Employee {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String name;
private String salary;
#Transient
private String phnNum;
#Enumerated(EnumType.STRING)
private EmployeeType type;
#ElementCollection
#CollectionTable(name="vacations" , joinColumns=#JoinColumn(name="Emp_Id"))
private Collection<Vacation> vacationBooking;
#ElementCollection
private Set<String> nickNames;
...................
with this code the "vacation" and "employee_nickname" two tables are created in schema. but i want to declare the one primary-key column in both table . what i do for this?
It looks like a primary key per se is not supported by JPA 2.0:
From Wikibooks:
The JPA 2.0 specification does not provide a way to define the Id in the Embeddable. However, to delete or update an element of the ElementCollection mapping, some unique key is normally required. Otherwise, on every update the JPA provider would need to delete everything from the CollectionTable for the Entity, and then insert the values back. So, the JPA provider will most likely assume that the combination of all of the fields in the Embeddable are unique, in combination with the foreign key (JoinColumn(s)). This however could be inefficient, or just not feasible if the Embeddable is big, or complex.
Some JPA providers may allow the Id to be specified in the Embeddable, to resolve this issue. Note in this case the Id only needs to be unique for the collection, not the table, as the foreign key is included. Some may also allow the unique option on the CollectionTable to be used for this. Otherwise, if your Embeddable is complex, you may consider making it an Entity and use a OneToMany instead.
Do you mean that you want to assign 'id' from Employee table as foreign key to the Vacation table?
In that case, you should use #OneToMany instead of #ElementCollection
I have a question about Hibernate ManyToMany mappings. I have two classes A and B and the mapping between them is a ManyToMany mapping resolved by Hibernate:
#Entity
#Table(name="A")
public class A {
#Id
#GeneratedValue
private Long id;
#ManyToMany
#JoinTable(name="C", joinColumns=#JoinColumn(name="a_id"), inverseJoinColumns=#JoinColumn(name="b_id"))
private Set bs;
}
#Entity
#Table(name="B")
public class B {
#Id
#GeneratedValue
private Long id;
#ManyToMany(mappedBy="bs")
private Set bs;
}
As you can see, the Join Table I use is C. The foreign keys to A and B are "a_id" and "b_id". My understanding is, that Hibernate creates a composed Primary Key with a_id and b_id for table C.
I don't want to have an entity C in my model. But instead of a composed primary key on table C, I would like to have a generated ID and a unique constraint on the fields a_id and b_id.
Is it possible to tell Hibernate to use a separate primary key? Without adding an entity C?
I would appreciate any help.
Thanks a lot!
You should do iyt like this. But it can be appled only for list (not for sets)
#Entity
#TableGenerator(name="ids_generator", table="IDS")
public class Passport {
...
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name="PASSPORT_VISASTAMP")
#CollectionId(
columns = #Column(name="COLLECTION_ID"),
type=#Type(type="long"),
generator = "ids_generator"
)
private Collection<Stamp> visaStamp = new ArrayList();
...
}
I don't think it is possible. And I don't see a problem in defining a C entity.
If you have any additional information ind the join-table, it will not be accessible to you, because your Set contains the target entity - A or B.
Also, your Sets would better make use of generics - i.e. Set<A> and Set<B>.
Btw, Hibernate might not be alarmed by the fact that the table creates another entity - using your current mapping might work (disregarding completely the id column). When you said "Hibernate creates", I assumed you are generating your schema from your entity model. Now it seems it's the opposite, so give it a try.
But instead of a composed primary key on table C, I would like to have a generated ID and a unique constraint on the fields a_id and b_id.
Normally the primary key of the JoinTable is made of the combination of both foreign keys. At least, this is what JPA would generate. But if you don't use the JPA provider to generate the model and if the PK can be generated by the database (using an IDENTITY column, a trigger, etc), then you should be able to use the C table for your ManyToMany association (without having to introduce an extra entity and to transform the relation in two OneToMany). Did you actually try?
#Entity
public class MUser implements Serializable, MemoEntity {
private static final long serialVersionUID = 1L;
#Id
private String email;
#OneToMany(cascade=CascadeType.ALL, orphanRemoval=true)
private Set<Meaning> mengs = new HashSet<Meaning>();
Shouldn't this mean that I get the constraint with a "on delete cascade"?
This is what gets generated instead:
CREATE TABLE MUSER_MEANING (MUser_EMAIL VARCHAR(255) NOT NULL, mengs_OBJID INTEGER NOT NULL, PRIMARY KEY (MUser_EMAIL, mengs_OBJID))
CREATE TABLE MUSER_MEANING (MUser_EMAIL VARCHAR(255) NOT NULL, mengs_OBJID INTEGER NOT NULL, PRIMARY KEY (MUser_EMAIL, mengs_OBJID))
ALTER TABLE MEANING ADD CONSTRAINT MEANING_USR_EMAIL FOREIGN KEY (USR_EMAIL) REFERENCES MUSER (EMAIL)
ALTER TABLE MUSER_MEANING ADD CONSTRAINT MSRMEANINGMsrEMAIL FOREIGN KEY (MUser_EMAIL) REFERENCES MUSER (EMAIL)
I'm trying to make it as such that deleting a MUser deletes all Meanings associated to it.
Why does not jpa2/eclipselink generate on delete cascade SQL?
Because that's not how things work. Specifying a cascade=REMOVE means that the remove operation will be cascaded to entities by the JPA provider, not at the database level using a constraint.
Some providers do have extensions to use a cascade delete constraint at the database level instead of the regular mechanism. For example with Hibernate, you can specify:
#OnDelete(action=OnDeleteAction.CASCADE) on joined subclasses: use a SQL cascade delete on deletion instead of the regular Hibernate mechanism.
But I don't know if EclipseLink has something equivalent.
References
JPA 2.0 Specification
Section 3.2.3 "Removal"
Hibernate Annotations Reference Guide
2.4. Hibernate Annotation Extensions