DataNucleus JDO on MySQL fails with FK violation on 1:1 relations - mysql

I have issues persisting a simple 2 classes on DataNucleus 3.1.3 on MySQL, where DataNucleus seems to create invalid foreign-keys, ending up in a "foreign key constraint fails" -exception from database.
Here my classes:
// datastore since i dont care about identity here
#PersistenceCapable(identityType = IdentityType.DATASTORE)
class A {
#Persistent
int x;
#Persistent
int y;
}
// identity type:application here to enable id lookups
#PersistenceCapable
class B {
#PrimaryKey
#Persistent(valueStrategy = IdGeneratorStrategy.NATIVE)
long id;
#Persistent
double longitude;
#Persistent
double latitude;
// simple 1:1 unidirectional
#Persistent
A a;
}
The schemaTool created the tables (InnoDB) which looks good, but an insert fails, here the logs:
12:54:11,369 DEBUG [DataNucleus.Datastore.Native] - INSERT INTO `A` (`X`,`Y`) VALUES (<1>,<1>)
12:54:11,387 DEBUG [DataNucleus.Datastore.Persist] - Execution Time = 18 ms (number of rows = 1)
12:54:11,398 DEBUG [DataNucleus.Datastore.Persist] - Object "foo.A#624af1e" was inserted in the datastore and was given strategy value of "3"
12:54:11,403 DEBUG [DataNucleus.Datastore] - Closing PreparedStatement "org.datanucleus.store.rdbms.ParamLoggingPreparedStatement#6f5ba238"
12:54:11,404 DEBUG [DataNucleus.Datastore.Native] - INSERT INTO `B` (`LONGITUDE`,`LATITUDE`,`A_A_ID_OID`) VALUES (<0.5099776394799052>,<0.6191090630996077>,<51>)
12:54:11,419 WARN [DataNucleus.Datastore.Persist] ... Cannot add or update a child row: a foreign key constraint fails (`xperimental`.`B`, CONSTRAINT `B_FK1` FOREIGN KEY (`A_A_ID_OID`) REFERENCES `A` (`A_ID`))
Looking at the logs on lines (3) and (5) its very suspicious that an insert into table A returned a PK of "3" but DataNucleus instead uses a value of "51" as FK on A when inserting data into table B which causes the violation.
Where is the issue? Thanks
UPDATE: the resources
Class A
package jdotest.a;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
#PersistenceCapable(identityType = IdentityType.DATASTORE)
public class A {
#Persistent
private int x;
#Persistent
private int y;
public int getX() {
return x;
}
public int getY() {
return y;
}
}
Class B
package jdotest.b;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import jdotest.a.A;
#PersistenceCapable
public class B {
#PrimaryKey
#Persistent(valueStrategy = IdGeneratorStrategy.NATIVE)
long id;
#Persistent
double longitude;
#Persistent
double latitude;
// simple 1:1 unidirectional
#Persistent
A a;
public long getId() {
return id;
}
public double getLongitude() {
return longitude;
}
public double getLatitude() {
return latitude;
}
public void setA(A a) {
this.a = a;
}
public A getA() {
return a;
}
}
Dao
package dao;
import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.Transaction;
import jdotest.b.B;
public class BDao {
public void write(B b) {
PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory("cloud-sql");
PersistenceManager pm = pmf.getPersistenceManager();
Transaction tx = pm.currentTransaction();
try {
tx.begin();
pm.makePersistent(b);
tx.commit();
} finally {
if (tx.isActive())
tx.rollback();
pm.close();
}
}
}
execution
package exec;
import jdotest.a.A;
import jdotest.b.B;
import dao.BDao;
public class Ex{
public void persist(){
A a = new A();
B b = new B();
b.setA(a);
new BDao().write(b); //<-- exception
}
}
the exception *
java.sql.SQLException: Cannot add or update a child row: a foreign key constraint fails (xperimental.b, CONSTRAINT B_FK1 FOREIGN KEY (A_A_ID_OID) REFERENCES a (A_ID))

Related

Spring Boot- Duplicate entry for key 'PRIMARY'

I am new to Spring Boot. I am trying to use the save() functionality via the JPA library using Postman for the first time. My database is a legacy Mysql database. Generically speaking, this table contains data of baseball players who have been drafted into a fantasy baseball league. The primary key of my table is 'play_id', and I also track the player's 'mlb_id' (Major League Baseball's unique identifier) in the same table.
Here is my code:
Table setup in Mysql:
CREATE TABLE `mlb_rosters` (
`play_id` int(10) NOT NULL,
`mlb_id` int(10) NOT NULL,
`name_first` varbinary(255) NOT NULL,
`name_last` varbinary(255) NOT NULL,
`bats` varchar(1) NOT NULL,
`throws` varchar(1) NOT NULL,
`birthday` date NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `mlb_rosters`
ADD PRIMARY KEY (`play_id`),
ADD UNIQUE KEY `mlb_id` (`mlb_id`),
ADD UNIQUE KEY `mlb_id_2` (`mlb_id`);
ALTER TABLE `mlb_rosters`
MODIFY `play_id` int(10) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=6730;
I also ran insert statements for approximately ~1500 players, so this is not a blank table.
My object in Springboot:
package com.example.demo.entities;
import javax.persistence.*;
#Entity
#Table(name="mlb_rosters")
public class IbcMlbPlayer {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="play_id", columnDefinition = "int(10)")
private Integer playId;
#Column(name="mlb_id")
private Integer mlbId;
#Column(name="name_first", columnDefinition = "varbinary(255)")
private String nameFirst;
#Column(name="name_last", columnDefinition = "varbinary(255)")
private String nameLast;
#Column(name="bats")
private String bats;
#Column(name="throws")
private String thrws;
#Column(name="birthday")
private String birthday;
public IbcMlbPlayer(){
}
public Integer getPlayId() {
return playId;
}
public void setPlayId(Integer playId) {
this.playId = playId;
}
public Integer getMlbId() {
return mlbId;
}
public void setMlbId(Integer mlbId) {
this.mlbId = mlbId;
}
public String getNameFirst() {
return nameFirst;
}
public void setNameFirst(String nameFirst) {
this.nameFirst = nameFirst;
}
public String getNameLast() {
return nameLast;
}
public void setNameLast(String nameLast) {
this.nameLast = nameLast;
}
public String getBats() {
return bats;
}
public void setBats(String bats) {
this.bats = bats;
}
public String getThrws() {
return thrws;
}
public void setThrws(String thrws) {
this.thrws = thrws;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
}
The relevant path of my controller:
#PostMapping(value = "/saveIbcMlbPlayer")
public IbcMlbPlayer saveIbcMlbPlayer(#RequestBody IbcMlbPlayer ibcMlbPlayer){
return ibcMlbPlayerDao.save(ibcMlbPlayer);
}
My Dao:
package com.example.demo.dao;
import com.example.demo.entities.IbcMlbPlayer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface IbcMlbPlayerDao extends JpaRepository<IbcMlbPlayer, Integer> {
}
When I attempt to do a Post request to the save path and pass in the JSON object of the player who I'm attempting to create, I get the following error:
Duplicate entry '25' for key 'PRIMARY'
In this case, I've tried this 25 times, so Postman/Spring Boot keep incrementing the 'play_id' field by 1 (this number goes up in the error message by one each time I test).
I understand the error, for whatever reason, Spring Boot isn't getting the max value of the 'play_id' field, incrementing it by one, and then attempting to do the insert. I would have expected 'play_id' to be 6730, which I believe is the table's max play_id plus one. Does anyone know how to fix this? Any help would be really appreciated!
AUTO shouldn't be used as GenerationType you must use IDENTITY
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="play_id", columnDefinition = "int(10)")
private Integer playId;

Spring Hibernate - Invalid value for getLong() - 'United Kingdom - UTC +0:00'

I guess hibernate is trying to assign a String value fetched from the database to long.Have done many-to-one unidirectional mapping.I'm trying to display the values from the region table in a drop down in CorporateGroupForm.jsp
CorporateGroup.java
#Entity
#Table(name="corporate_group")
public class CorporateGroup extends BaseObject implements Serializable {
private Region region;
private Long id;
#ManyToOne(cascade=CascadeType.ALL)
#JoinColumn(name="id")
public Region getRegion() {
return region;
}
public void setRegion(Region region) {
this.region = region;
}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="id")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
} }
corporateGroupForm.jsp
<li>
<appfuse:label styleClass="desc" key="corporateGroupDetail.region"/>
<select name="regionDesc">
<option value=""><fmt:message key="select.pleaseSelect"/></option>
<c:forEach var="region" items="${regionsList}">
<c:set var="selected" value="${corporateGroup.region ne null and corporateGroup.region.regionDesc eq region.regionDesc}"/>
<option ${selected ? 'selected' : ''} value="${region.regionDesc }">${region.regionDesc } </option>
</c:forEach>
</select>
</li>
DB:
CREATE TABLE `corporate_group` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`comment` text,`name` varchar(255) NOT NULL,`parent_id`bigint(20) DEFAULT NULL,`primary_contact_id` bigint(20) DEFAULT NULL,`account_manager_email` varchar(255) DEFAULT NULL,`dateCreated` datetime DEFAULT CURRENT_TIMESTAMP,`region_description` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `name` (`name`),KEY `FK61BCC225C8E0340A` (`parent_id`),KEY `FK61BC225F0655E4F` (`primary_contact_id`),KEY `FK_REGION_idx` (`region_description`),CONSTRAINT `fk_region` FOREIGN KEY (`region_description`) REFERENCES `region` (`region_description`) ON DELETE NO ACTION ON UPDATE NO ACTION,CONSTRAINT `FK61BC225F0655E4F` FOREIGN KEY (`primary_contact_id`) REFERENCES `app_user` (`id`),CONSTRAINT `FK61BCC225C8E0340A` FOREIGN KEY (`parent_id`) REFERENCES `corporate_group` (`id`)) ENGINE=InnoDB AUTO_INCREMENT=843 DEFAULT CHARSET=latin1;
CREATE TABLE `region` (`id` bigint(20) NOT NULL,`country_code` varchar(50) NOT NULL,country_name` varchar(100) NOT NULL,`time_zone` varchar(100) NOT NULL,`region_description` varchar(255) NOT NULL,PRIMARY KEY (`id`),UNIQUE KEY `description_UNIQUE` (`region_description`),KEY `id` (`id`),KEY `region_description` (`region_description`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Exception Stack Trace :
Hibernate: select corporateg0_.id as id2_,
corporateg0_.account_manager_email as account2_2_,
corporateg0_.comment as comment2_, corporateg0_.name as name2_,
corporateg0_.parent_id as parent6_2_, corporateg0_.primary_contact_id
as primary5_2_, corporateg0_.region_description as region7_2_ from
corporate_group corporateg0_ order by corporateg0_.name WARN
[http-bio-9080-exec-1] JDBCExceptionReporter.logExceptions(77) | SQL
Error: 0, SQLState: S1009 WARN [http-bio-9080-exec-1]
JDBCExceptionReporter.logExceptions(77) | SQL Error: 0, SQLState:
S1009 ERROR [http-bio-9080-exec-1]
JDBCExceptionReporter.logExceptions(78) | Invalid value for getLong()
- 'UK -UTC +0:00' ERROR [http-bio-9080-exec-1] JDBCExceptionReporter.logExceptions(78) | Invalid value for getLong()
- 'UK -UTC +0:00'
The error on the web page :
Data Access Failure
Hibernate operation: could not execute query; uncategorized SQLException for SQL [select corporateg0_.id as id2_, corporateg0_.account_manager_email as account2_2_, corporateg0_.comment as comment2_, corporateg0_.name as name2_, corporateg0_.parent_id as parent7_2_, corporateg0_.primary_contact_id as primary5_2_, corporateg0_.region_description as region6_2_ from corporate_group corporateg0_ order by corporateg0_.name]; SQL state [S1009]; error code [0]; Invalid value for getLong() - 'UK -UTC +0:00'; nested exception is java.sql.SQLException: Invalid value for getLong() - 'UK -UTC +0:00'
Region.java
#Entity
#Table(name = "region")
public class Region extends BaseObject implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="id")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
private String countryCode;
private String countryName;
private String timeZone;
private String regionDesc;
#Column(name="country_code",nullable=false)
public String getCountryCode() {
return countryCode;
}
public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
#Column(name="country_name",nullable=false)
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
#Column(name="time_zone",nullable=false)
public String getTimeZone() {
return timeZone;
}
public void setTimeZone(String timeZone) {
this.timeZone = timeZone;
}
#Column(name="region_description",nullable=false)
public String getRegionDesc() {
return regionDesc;
}
public void setRegionDesc(String regionDesc) {
this.regionDesc = regionDesc;
}
#Override
public String toString() {
StringBuffer strBuff = new StringBuffer();
if (getId() != null) {
strBuff = strBuff.append("ID:" + getId() + ",");
strBuff = strBuff.append("Country Name:" + getCountryName() + ",");
strBuff = strBuff.append("Country Code:" + getCountryCode() + ",");
strBuff = strBuff.append("Timezone:" + getTimeZone() + ",");
strBuff = strBuff.append("Region Description:" + getRegionDesc() + ",");
}
return strBuff.toString();
}
#Override
public boolean equals(Object o) {
// TODO Auto-generated method stub
if (!(o instanceof Region)) {
return false;
}
Region reg = (Region) o;
return !(regionDesc != null ? !regionDesc.equals(reg.getRegionDesc()) : reg.getRegionDesc() != null);
}
#Override
public int hashCode() {
// TODO Auto-generated method stub
int hashcode = 0;
if (this.regionDesc != null) {
hashcode = hashcode + this.regionDesc.hashCode();
}
return hashcode;
}
}
Now a different error :
ERROR [localhost-startStop-1 ContextLoader.initWebApplicationContext(215) | Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name '_filterChainProxyPostProcessor': BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.config.internalTransactionAdvisor': Cannot create inner bean '(inner bean)' of type [org.springframework.transaction.interceptor.TransactionInterceptor] while setting bean property 'transactionInterceptor'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#1': Cannot resolve reference to bean 'transactionManager' while setting bean property 'transactionManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in class path resource [applicationContext-dao.xml]: Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException:Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext-dao.xml]: Invocation of init method failed; nested exception is org.hibernate.MappingException: Repeated column in mapping for entity: com.canvas8.model.CorporateGroup column: id (should be mapped with insert="false" update="false")
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:405)
at java.security.AccessController.doPrivileged(Native Method)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:220)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:881)
at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:606)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:366)
at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:255)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:199)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4994)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5492)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:649)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1081)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1877)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
In your CorporateGroup entity class, you mapped region with region_description of Region entity which has a primary key of Long
#ManyToOne(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
#JoinColumn(name="region_description")
public Region getRegion() {
return region;
}
What you can do is you can map region member variable of CorporateGroup to primary key of Region entity class not the region_description.
Regarding this error :
Repeated column in mapping for entity:
com.canvas8.model.CorporateGroup column: id (should be mapped with
insert="false" update="false")
The error message is obvious, you have mapped same column twice. Refer this and fix the issue.
Hope this helps!
I was able to specify the referenced column name to resolve the issue for me. I didn't want to eager fetch the entities since it would only be used sometimes and didn't have permissions to modify the database schema.
Try this:
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "region_description", referencedColumnName = "region_description")
private Region region;

Spring Hibernate MySql - Cannot add foreign key constraint

I have a running Spring Boot application with Mysql and Hibernate.
While launching it, i'm getting this error
Unsuccessful: alter table SMARTPARK.illuminazione add constraint FK_4kmtr3q9e2hnaoutsxgahhm63 foreign key (id_interruttore) references SMARTPARK.interruttori (id_interruttore)
2016-05-05 08:46:35 ERROR SchemaUpdate:262 - Cannot add foreign key constraint
I have two table/entities
Illuminazione.java is (just the interesting parts...)
#Entity
#Table(name = "illuminazione", catalog = "SMARTPARK")
public class Illuminazione {
private int idilluminazione;
private Interruttore interruttore;
private Date dateTime;
private Date lastDateTime;
private boolean isLit;
#ManyToOne
#JoinColumn(name = "id_interruttore")
public Interruttore getInterruttore() {
return this.interruttore;
}
public void setInterruttore(Interruttore interruttore) {
this.interruttore = interruttore;
}
In Interruttore.java I have the #OneToMany relation with Illuminazione
#Entity
#Table(name = "interruttori", catalog = "SMARTPARK", uniqueConstraints = #UniqueConstraint(columnNames = "id_interruttore"))
public class Interruttore implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private int idInterruttore;
private int numeroInterruttore;
private String nomeInterruttore;
private String descrizione;
private List<Luce> luci;
private GpioController gpio;
private GpioPinDigitalOutput relePin;
private Pin pin;
private boolean remoto;
private boolean stato;
private Date dateTime;
private Set<Illuminazione> illuminazione;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "interruttore")
public Set<Illuminazione> getIlluminazione() {
return illuminazione;
}
public void setIlluminazione(Set<Illuminazione> illuminazione) {
this.illuminazione = illuminazione;
}
Every time I start the application, during the boot i'm getting this error (even if the application seems working good...)
I had the same error message, which I found out was caused by incorrect annotations. Hibernate was trying to run
alter table cidades
add constraint FKdt0b3ronwpi1upsrhaeq6r69n
foreign key (estado_id)
references estados (id)
And when I looked at my Cidade.java, I found this mapping
#ManyToOne
#JoinColumn(name = "cidade_id")
private Estado estado;
The error was in "cidade_id", which should have been "estado_id". It would be great if #besmart could provide the DB table info, since the error could be caused by a typo (e.g. id_interruttore could actually be id_interruttori).
I hope this helps someone in the future.
I hit similar problem .
To me apparently hibernate/Spring was NOT using mysql Engine -INNODB , you need engine INNODB for mysql to generate foreign key constraint.
Using the following properties in application.properties, makes spring boot/hibernate to use mysql engine INNODB. So foreign key constraint works and hence also delete cascade
spring.jpa.hibernate.use-new-id-generator-mappings=true
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect

Dynamically Changing Table Names

I am currently working with a database that has read and write tables.
There are always two tables with the same schema, distinguished by a number as suffix, eg. table1 and table2.
Now, there is another source where I get the current number from. I have to use this number to select from the corresponding table with the matching suffix.
Right now, for every table i have a #MappedSuperclass containing the schema and two implementation classes specifying the table name via #Table(name = "..1") and #Table(name = "..2").
This solution works but by now I discovered a lot of drawbacks and fear there will be many more. Is there another, better way to solve this?
Unfortunately, I could not find out what this kind of database mechanism is called hence I could not find any other sources on the internet.
Thank you in advance!
The most obvious solution:
if ( num == 1 )
{
Table1 table1 = createTable1();
table1.set...;
entityManager.persist( table1 );
} else
{
Table2 table2 = createTable2();
table2.set...;
entityManager.persist( table2 );
}
Or with constructor calling by name (with Lombok annotations):
#Entity
#Data
public class CommonBase
{}
#Entity
#Data
public class Table1 extends CommonBase
{}
#Entity
#Data
public class Table2 extends CommonBase
{}
#Stateless
#LocalBean
public class CommonBaseBean
{
#Inject
private CommonBaseBUS commonBaseBUS;
protected void clientCode()
{
Table0 t0 = (Table0) commonBaseBUS.createEntityByIndex( 0 );
t0.set...();
commonBaseBUS.persisEntity( t0 );
Table1 t1 = (Table1) commonBaseBUS.createEntityByIndex( 1 );
t1.set...();
commonBaseBUS.persisEntity( t1 );
}
}
#Dependent
class CommonBaseBUS
{
#Inject
private CommonBaseDAL commonBaseDAL;
#Setter
private String entityBaseName = "qualified.path.Table";
public CommonBase createEntityByIndex( int index_ ) throws ClassNotFoundException
{
String entityName = entityBaseName + Integer.toString( index_ );
return createEntityByName( entityName );
}
public void persisEntity( CommonBase cb_ )
{
commonBaseDAL.persistEntity( cb_ );
}
protected CommonBase createEntityByName( String entityName_ ) throws ClassNotFoundException
{
Class<?> c = Class.forName( entityName_ );
try
{
return (CommonBase) c.newInstance();
}
catch ( InstantiationException | IllegalAccessException ex )
{
throw new ClassNotFoundException();
}
}
}
#Dependent
class CommonBaseDAL
{
#PersistentContext
private EntityManager em;
public void persisEntity( CommonBase cb_ )
{
em.persistEntity( cb_ );
}
}

Hibernate generating incorrect MySQL script

I have two Classes mapping each one to an Entity in MySQL database. Whenever I try to map into to DB I got an MySQL Error
Class Owner:
#Entity
public class Owner {
#Id #GeneratedValue
private int idOwner;
public int getIdOwner() {
return idOwner;
}
public void setIdOwner(int idOwner) {
this.idOwner = idOwner;
}
}
Class Car with FK:
#Entity
public class Car {
#Id #GeneratedValue
private int idCar;
#ManyToOne
#JoinColumn( name = "idOwner")
private Owner owner;
public int getIdCar() {
return idCar;
}
public void setIdCar(int idCar) {
this.idCar = idCar;
}
public Owner getOwner() {
return owner;
}
public void setOwner(Owner owner) {
this.owner = owner;
}
}
Code running:
EntityManagerFactory f = Persistence.createEntityManagerFactory("glorious");
EntityManager em = f.createEntityManager();
EntityTransaction t = em.getTransaction();
t.begin();
Car c = new Car();
Owner o = new Owner();
c.setOwner(o);
em.persist(c);
em.persist(o);
t.commit();
f.close();
em.close();
Error:
GRAVE: Unsuccessful: alter table .Car add index FK107B43F620606 (idOwner), add constraint FK107B43F620606 foreign key (idOwner) references .Owner (idOwner)
27/05/2014 20:35:01 org.hibernate.tool.hbm2ddl.SchemaExport create
GRAVE: Can't create table 'glorious.#sql-2aa_1f8' (errno: 150)
MySQL Version : 5.5.34
Engine : InnoDB
Hibernate Dialect : MySQL5InnoDBDialect
I took the script generated by Hibernate and tested it directly in phpMyAdmin, it didn't work.
SQL script :
alter table .Car add index FK107B43F620606 (idOwner), add constraint FK107B43F620606 foreign key (idOwner) references .Owner (idOwner)
If I fix the script by replacing the tables name with , e.g. Car or glorious.Car than it works. Anyone has an idea?
Solved it. My persistence.xml had the property default_schema set to empty. That's why no DB name was appearing before the table's name.