Home » Eclipse Projects » EclipseLink » EclipseLink can't create foreign key constraints(It seems that EclipseLink has some problems creating foreign key constraints based on JPA annotations)
EclipseLink can't create foreign key constraints [message #1748542] |
Thu, 24 November 2016 09:00 |
|
Hello everyone,
I'm currently trying to use EclipseLink v2.6.4 for some tests in which I need a javax.persistence.EntityManager instance. I'm using an Apache Derby in-memory database for my tests. And I want to use my JPA annotation so that EclipseLink can create the database structure when "booting up". But it seems it doesn't work correctly.
My test:
public class ArticleEntityTest {
private EntityManagerFactory entityManagerFactory;
private EntityManager entityManager;
@Before
public void setUp() {
Map<String, String> properties;
org.eclipse.persistence.jpa.PersistenceProvider pp;
properties = new HashMap<>();
properties.put(PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML,
"META-INF/persistence-test.xml");
pp = new org.eclipse.persistence.jpa.PersistenceProvider();
this.entityManagerFactory = pp.createEntityManagerFactory("orderingManager", properties);
Assert.assertNotNull("EntityManagerFactory should not be null", this.entityManagerFactory);
this.entityManager = this.entityManagerFactory.createEntityManager();
}
@Test
public void test() {
this.entityManager.getTransaction().begin();
this.entityManager.getTransaction().commit();
}
}
META-INF/persistence-test.xml (**** are because of the forum error 'You can only use links to eclipse.org sites while you have fewer than 1 message.' ):
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="****/xml/ns/persistence" xmlns:xsi="****/2001/XMLSchema-instance"
xsi:schemaLocation="****/xml/ns/persistence ****/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="orderingManager" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>com.sample.ejb.marketplace.ArticleEntity</class>
<class>com.sample.ejb.marketplace.DealerEntity</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
<property name="javax.persistence.jdbc.url" value="jdbc:derby:memory:myDB;create=true" />
<property name="eclipselink.target-database" value="Derby" />
<property name="eclipselink.ddl-generation" value="create-tables" />
<property name="eclipselink.logging.level.sql" value="FINE"/>
<property name="eclipselink.logging.parameters" value="true"/>
</properties>
</persistence-unit>
</persistence>
The entity classes:
@MappedSuperclass
public abstract class AbstractEntity implements Serializable {
/** The version of this class. */
private static final long serialVersionUID = 959294142676510096L;
/** The ID. */
@Id
@GeneratedValue(generator = "id")
@GenericGenerator(name = "id", strategy = "increment")
private Long id;
/**
* <p>
* Creates an entity.
* </p>
*/
public AbstractEntity() {
super();
}
/**
* <p>
* Returns the ID.
* </p>
*
* @return The ID.
*/
public Long getId() {
return this.id;
}
/**
* <p>
* Sets the ID.
* </p>
*
* @param id
* The ID.
*/
public void setId(Long id) {
this.id = id;
}
}
@Entity
@Table(name = "dealer", uniqueConstraints = {
@UniqueConstraint(name = "dealer_name_unique_key", columnNames = { "name" }) })
public class DealerEntity extends AbstractEntity {
/** The version of this class. */
private static final long serialVersionUID = 3751322320007565926L;
/** The name. */
@Column(name = "name", nullable = false, length = 256)
private String name;
/**
* <p>
* Creates a dealer.
* </p>
*/
public DealerEntity() {
super();
}
/**
* <p>
* Returns the name.
* </p>
*
* @return The name.
*/
public String getName() {
return this.name;
}
/**
* <p>
* Sets the name.
* </p>
*
* @param name
* The name.
*/
public void setName(String name) {
this.name = name;
}
}
@Entity
@Table(name = "article", uniqueConstraints = {
@UniqueConstraint(name = "article_number_unique_key", columnNames = { "number" }) })
public class ArticleEntity extends AbstractEntity {
/** The version of this class. */
private static final long serialVersionUID = 7373588833516503465L;
/** The article number. */
@Column(name = "number", nullable = false, length = 256)
private String number;
/** The name. */
@Column(name = "name", nullable = false, length = 256)
private String name;
/** The dealer. */
@ManyToOne(targetEntity = DealerEntity.class, cascade = { CascadeType.ALL })
@JoinColumn(name = "dealer_id", referencedColumnName = "id", nullable = false, foreignKey = @ForeignKey(name = "article_dealer_foreign_key"))
private DealerEntity dealer;
/**
* <p>
* Creates an article.
* </p>
*/
public ArticleEntity() {
super();
}
/**
* <p>
* Returns the article number.
* </p>
*
* @return The article number.
*/
public String getNumber() {
return this.number;
}
/**
* <p>
* Sets the article number.
* </p>
*
* @param number
* The article number.
*/
public void setNumber(String number) {
this.number = number;
}
/**
* <p>
* Returns the name.
* </p>
*
* @return The name.
*/
public String getName() {
return this.name;
}
/**
* <p>
* Sets the name.
* </p>
*
* @param name
* The name.
*/
public void setName(String name) {
this.name = name;
}
/**
* <p>
* Returns the dealer.
* </p>
*
* @return The dealer.
*/
public DealerEntity getDealer() {
return this.dealer;
}
/**
* <p>
* Sets the dealer.
* </p>
*
* @param dealer
* The dealer.
*/
public void setDealer(DealerEntity dealer) {
this.dealer = dealer;
}
}
The output of the test:
[EL Fine]: 2016-11-24 09:35:04.112--Thread(Thread[main,5,main])--Configured server platform: org.eclipse.persistence.platform.server.jboss.JBossPlatform
[EL Config]: 2016-11-24 09:35:04.269--ServerSession(17037394)--Thread(Thread[main,5,main])--The access type for the persistent class [class com.sample.ejb.AbstractEntity] is set to [FIELD].
[EL Config]: 2016-11-24 09:35:04.301--ServerSession(17037394)--Thread(Thread[main,5,main])--The access type for the persistent class [class com.sample.ejb.marketplace.ArticleEntity] is set to [FIELD].
[EL Config]: 2016-11-24 09:35:04.316--ServerSession(17037394)--Thread(Thread[main,5,main])--The access type for the persistent class [class com.sample.ejb.marketplace.DealerEntity] is set to [FIELD].
[EL Config]: 2016-11-24 09:35:04.332--ServerSession(17037394)--Thread(Thread[main,5,main])--The column name for element [id] is being defaulted to: ID.
[EL Config]: 2016-11-24 09:35:04.332--ServerSession(17037394)--Thread(Thread[main,5,main])--The alias name for the entity class [class com.sample.ejb.marketplace.ArticleEntity] is being defaulted to: ArticleEntity.
[EL Config]: 2016-11-24 09:35:04.347--ServerSession(17037394)--Thread(Thread[main,5,main])--The column name for element [id] is being defaulted to: ID.
[EL Config]: 2016-11-24 09:35:04.347--ServerSession(17037394)--Thread(Thread[main,5,main])--The alias name for the entity class [class com.sample.ejb.marketplace.DealerEntity] is being defaulted to: DealerEntity.
[EL Config]: 2016-11-24 09:35:04.347--ServerSession(17037394)--Thread(Thread[main,5,main])--The column name for element [id] is being defaulted to: ID.
[EL Info]: 2016-11-24 09:35:04.41--ServerSession(17037394)--Thread(Thread[main,5,main])--EclipseLink, version: Eclipse Persistence Services - 2.6.4.v20160829-44060b6
[EL Config]: 2016-11-24 09:35:04.425--ServerSession(17037394)--Connection(341878976)--Thread(Thread[main,5,main])--connecting(DatabaseLogin(
platform=>DerbyPlatform
user name=> ""
datasource URL=> "jdbc:derby:memory:myDB;create=true"
))
[EL Config]: 2016-11-24 09:35:05.393--ServerSession(17037394)--Connection(1241569743)--Thread(Thread[main,5,main])--Connected: jdbc:derby:memory:myDB
User: APP
Database: Apache Derby Version: 10.13.1.1 - (1765088)
Driver: Apache Derby Embedded JDBC Driver Version: 10.13.1.1 - (1765088)
[EL Info]: 2016-11-24 09:35:05.44--ServerSession(17037394)--Thread(Thread[main,5,main])--/file:/C:/Users/g.hohl/workspace/Test/ejb-remote-server/target/test-classes/_orderingManager login successful
[EL Fine]: 2016-11-24 09:35:05.721--ServerSession(17037394)--Connection(1241569743)--Thread(Thread[main,5,main])--CREATE TABLE article (ID BIGINT NOT NULL, name VARCHAR(256) NOT NULL, number VARCHAR(256) NOT NULL, dealer_id BIGINT NOT NULL, PRIMARY KEY (ID))
[EL Fine]: 2016-11-24 09:35:05.799--ServerSession(17037394)--Connection(1241569743)--Thread(Thread[main,5,main])--CREATE TABLE dealer (ID BIGINT NOT NULL, name VARCHAR(256) NOT NULL, PRIMARY KEY (ID))
[EL Fine]: 2016-11-24 09:35:05.799--ServerSession(17037394)--Connection(1241569743)--Thread(Thread[main,5,main])--ALTER TABLE article ADD CONSTRAINT article_number_un UNIQUE (number)
[EL Fine]: 2016-11-24 09:35:05.83--ServerSession(17037394)--Connection(1241569743)--Thread(Thread[main,5,main])--ALTER TABLE dealer ADD CONSTRAINT dealer_name_uniqu UNIQUE (name)
[EL Fine]: 2016-11-24 09:35:05.846--ServerSession(17037394)--Connection(1241569743)--Thread(Thread[main,5,main])--ALTER TABLE article ADD CONSTRAINT article_dealer_foreign_key FOREIGN KEY () REFERENCES ()
[EL Fine]: 2016-11-24 09:35:05.862--ServerSession(17037394)--Thread(Thread[main,5,main])--VALUES(1)
[EL Warning]: 2016-11-24 09:35:05.862--ServerSession(17037394)--Thread(Thread[main,5,main])--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.6.4.v20160829-44060b6): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLSyntaxErrorException: Syntax error: Encountered ")" at line 1, column 76.
Error Code: 30000
Call: ALTER TABLE article ADD CONSTRAINT article_dealer_foreign_key FOREIGN KEY () REFERENCES ()
Query: DataModifyQuery(sql="ALTER TABLE article ADD CONSTRAINT article_dealer_foreign_key FOREIGN KEY () REFERENCES ()")
[EL Fine]: 2016-11-24 09:35:05.862--ServerSession(17037394)--Connection(1241569743)--Thread(Thread[main,5,main])--CREATE TABLE SEQUENCE (SEQ_NAME VARCHAR(50) NOT NULL, SEQ_COUNT DECIMAL(15), PRIMARY KEY (SEQ_NAME))
[EL Fine]: 2016-11-24 09:35:05.908--ServerSession(17037394)--Connection(1241569743)--Thread(Thread[main,5,main])--SELECT * FROM SEQUENCE WHERE SEQ_NAME = 'id'
[EL Fine]: 2016-11-24 09:35:05.971--ServerSession(17037394)--Connection(1241569743)--Thread(Thread[main,5,main])--INSERT INTO SEQUENCE(SEQ_NAME, SEQ_COUNT) values ('id', 0)
The funny thing: I set some breakpoints in my Eclipse IDE and stepped through the DDL creation. And one time the org.eclipse.persistence.tools.schemaframework.ForeignKeyConstraint object gets the correct source field and target field set (by calling getSourceFields().add(String) and getTargetFields().add(String) - also there are addSourceField(String) and addTargetField(String) methods). But then a 2nd time a ForeignKeyConstraint object is created for exactly the same foreign key. And that time the source field and target field are not added.
A workaround would be to use the foreignKeyDefinition attribute of the @ForeignKey annotation. But then the same information has to be added again and to be hold in sync with the rest of the annotation. That doesn't seem to be a real solution to me.
Would be great if someone could tell me where my fault is.
|
|
| |
Goto Forum:
Current Time: Mon Sep 23 19:20:01 GMT 2024
Powered by FUDForum. Page generated in 0.02956 seconds
|