viernes, 2 de junio de 2017

Java Persistence API (JPA) con Hibernate y Eclipse IDE


Se aborda el tema de JPA con Hibernate y Eclipse IDE, se hacen ejemplos y configuraciones con MySQL y/o Oracle

http://hibernate.org/

NetBeans Lookup API

NetBeans Lookup API

Esta API tiene 2 distintos propositos/significados, ambos enfocadoes en desacoplar modulos
.- JDK 6 ServiceLoader Class. proveedores de servicios multiples cargados por la clase  "LookUp"
via interface compartida.
.- Context Sensitivity. objetos Netbeans, e.g., windows, tienen un "lookup", definiendo capacidades, las cuales cambian dinamicamente.

Ejemplo:
pequeño ejemplo de uso JDK 6 service load

Este no usa los netbeans modules, se creará una simple aplicación java
File -> New Project -> Java -> Java Application
esta definirá un servicio que será expuesta a traves de un ServiceInterface
Crearemos otra simple aplicación java, donde pondremos la primer aplicación java dentro del classpath de la segunda aplicación java. La segunda aplicación java definirá el ServiceProvider
el cual implementa la interface (ServiceInterface). Esto es posible por que la primera aplicación java esta en el classpath de la segunda aplicación java. La segunda aplicación java expondrá el ServiceProvider a través del mecanismo JDK 6 ServiceLoader Class, por medio del paquete java META-INF.services, lo que es lo mismo un folder META-INF y subfolder services. el cual contiene un archivo con el nombre calificado del ServiceInterface. (org.demo.services.ServiceInterface como esta definida en la primer aplicación java). Este archivo contiene los nombres calificados de los ServiceProviders definidos en la segunda aplicación java. (org.demo.ServiceProvider1, org.demo.ServiceProvider2).
  Posteriormente se crea una trecer aplicación java, que dependera de la primera y segunda aplicación (agregar a la librería), esta utilizará JDK ServiceLoader Class, para cargar los ServiceProviders a través de ServiceInterface. Esto es posible por que la segunda aplicación expone los servicios por medio del folder META-INF services.
  Adicionalmente y no necesario para la simplicidad de este ejemplo, se crea una cuarta aplicación java que duplica a la segunda aplicación java, que en este caso define un ServiceProviderB1.

La estructura de estas sencillas aplicaciones java se muestra en NetBeans en la siguiente figura


El diagrama UML



La ejecución de la tercera aplicación 3AppServiceDisplayer llamara metodos de las otras aplicaciones por medio de la interface, gracias a las dependecias que el JDK 6 class loader puede resolver.

run:
Service Called:returns ServiceProvider1 from 2AppDemoService which implements ServiceInterface from 1AppDemoService
Service Called:returns ServiceProvider2 from 2AppDemoService which implements ServiceInterface from 1AppDemoService
Service Called:returns ServiceProviderB1 from 4AppDemoService which implements ServiceInterface from 1AppDemoService
BUILD SUCCESSFUL (total time: 0 seconds)

El código en github
https://github.com/jalbertomr/simpleLookupAPI.git


Otra Forma de llegar al mismo objetivo es usar la plataforma de Netbeans Modules, los cuales se comunicarán entre ellos, así se ayuda a tener un código más organizado. Esto se logra
creando un projecto NetBeans Platform Applications

File -> New Project -> NetBeans Modules -> NetBeans Platform Applications
name: AppSimpleNetBeansModule

Se ajustan las librerias a incluir a lo básico:
Project Window -> click derecho en AppSimpleNetBeansModule -> Properties -> Libraries -> platform
  Se eligen solamente los paquetes básicos esto es bootstrap, Startup, Module System, File System, Utilities adicionalmente sugerirá netbeans resolver agregar más paquetes por dependencia a lo que asentiremos positivamente.
Se agrega un nuevo modulo a la aplicación creada:
AppSimpleNetBeansModule -> Modules -> click derecho -> add new...
 project name: ModuleAppSimple

Le agregamos una Module Installer
ModuleAppSimple -> new.. -> Module Installer

Al método restored() que se generó, simplemente  le agregamos un println("Hello world");



y ejecutamos la aplicación AppSimpleNetBeansModule

-------------------------------------------------------------------------------
Hello World!
INFO [org.netbeans.core.startup.NbEvents]: Turning on modules:
    org.openide.util.lookup [8.33.1 201609300101]
    org.openide.util [9.7.1 201609300101]
    org.openide.util.ui [9.6.1 201609300101]
    org.openide.modules [7.48.1 201609300101]
    org.openide.filesystems [9.10.1 201609300101]
    org.openide.filesystems.compat8 [9.9.1 201609300101]
    org.netbeans.libs.asm [5.3.1 201609300101]
    org.netbeans.demo [1.0 170926]
    org.netbeans.core.startup.base [1.62.1.1 1 201609300101]
    org.netbeans.bootstrap/1 [2.76.1 201609300101]
    org.netbeans.core.startup/1 [1.62.1.1 201609300101]
BUILD SUCCESSFUL (total time: 31 seconds)

Indica como módulos pueden comunicarse con otros en una forma desacoplada.

Realizando la misma tarea que se hizo en el ejemplo que utiliza JDK 6 Class loader, pero con la plataforma NetBeans Modules, tenemos una estructura como esta

Project Properties -> API Versioning -> Public packages se hacen publicos los paquetes para que tengan visibilidad por los módulos que los utilizarán, y en los módulos que los utilizarán o haran referencia a ellos, se los agregarán en su librería.



Ejecutando tenemos:
-------------------------------------------------------------------------------
Windows Restored...
Service Called: ServicePrivider1 from DemoServiceProviderB which implements ServiceInterface from DemoService
Service Called: ServiceProvider1 from DemoServiceProviderA which implements ServiceInterface from DemoService
Service Called: ServiceProvider2 from DemoServiceProviderA which implements ServiceInterface from DemoService
INFO [org.netbeans.core.startup.NbEvents]: Turning on modules:
    org.openide.util.lookup [8.33.1 201609300101]
    org.openide.util [9.7.1 201609300101]
    org.openide.util.ui [9.6.1 201609300101]
    org.openide.modules [7.48.1 201609300101]
    org.openide.filesystems [9.10.1 201609300101]
    org.openide.filesystems.compat8 [9.9.1 201609300101]
    org.netbeans.libs.asm [5.3.1 201609300101]
    org.netbeans.core.startup.base [1.62.1.1 1 201609300101]
    org.netbeans.bootstrap/1 [2.76.1 201609300101]
    org.netbeans.core.startup/1 [1.62.1.1 201609300101]
    org.demo.service [1.0 170610]
    org.demo.serviceProviderB [1.0 170610]
    org.demo.serviceProvider [1.0 170610]
    org.demo.consumer [1.0 170926]
BUILD SUCCESSFUL (total time: 26 seconds)

El LookupAPI puede hacer más, No solamente es un service loader, en primera instancia tiene un listener el cual detecta cuando hay un nuevo service provider cargado por el runtime container. Esto permite integrar un módulo dinámicamente a una aplicación en runtime.
en segundo lugar se puede implementar context sensitivity

jueves, 1 de junio de 2017

Top Ten NetBeans APIs


Problem Statement

Típico problema del código espageti , Netbeans responde a este problema permitiendo dividir el código en modulos, así un modulo solo puede ser utilizado por otro, si intencinalmente se le  indica la dependencia entre ellos. en el nombre y la versión de los modulos dependientes.
En segundo, los APIS de Netbeans ya ofrecen soluciones sobre diferentes necesidades a explotar en el sistema, esto es, ofrece librerias como windows system API, FileSystem API...
Runtime Container
Netbeans application platform debe tener minimo los siguientes modulos





por ejemplo el método main es proporcionado por el modulo Startup, adicionalmente el runtime container en runtime descubre los modulos que conforman la aplicación, resolviendo las dependencias entre estos.

Module System API
   Un Modulo tiene la funcion de disuadir la construcción de código espagetti, debido a que el código en un modulo es solo usado por otro módulo cuando se establece un contrato entre los módulos. Da puntos de entrada a en los ciclos de vida de los módulos.


NetBeans IDE
1.- Runtime Container API
2.- Module System API
3.- Lookup API
4.- Window System API
5.- FileSystem API
6.- Nodes API
7.- Loaders API
8.- Explorer & Property Sheet API
9.- Visual Library API
10.- Utilities API

Referencias:
    NetBeans Top 10 APIs, Geertjan

JavaEE JPA API Laboratorio



JPA Cases

Estos Son ejemplos prácticos de generación de tablas de bases de datos a partir de entidades (@Entity)  annotations en Java JPA

Enlace a archivo work con imagenes

JPA_1_Simple Table

@Entity
public class Tabla implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String nombre;
    private String apellido;
    private Double valDouble;
    private Integer valInteger;
    private boolean valboolean;
    @Temporal(DATE)
    private java.util.Date utilDate;
    private java.sql.Date sqlDate;
    private Time sqlTime;
    private Timestamp sqlTimeStamp;
    @Lob
    private String descripcion;
    @Lob
    @Column(name="EMP_PIC",columnDefinition="BLOB NOT NULL")
    private byte[] pic;
   
    public Long getId() {
        return id;
    } …

Genera


drop table DEVELOP.TABLA cascade constraints;

/*==============================================================*/
/* Table: TABLA                                                 */
/*==============================================================*/
create table DEVELOP.TABLA
(
   ID                   NUMBER(19)           not null,
   APELLIDO             VARCHAR2(255),
   DESCRIPCION          CLOB,
   NOMBRE               VARCHAR2(255),
   EMP_PIC              BLOB                 not null,
   SQLDATE              DATE,
   SQLTIME              TIMESTAMP,
   SQLTIMESTAMP         TIMESTAMP,
   UTILDATE             DATE,
   VALDOUBLE            NUMBER(19,4),
   VALINTEGER           NUMBER(10),
   VALBOOLEAN           NUMBER(1)            default 0,
   constraint SYS_C007261 primary key (ID)
         using index pctfree 10
   initrans 2
   storage
   (
       initial 64K
       next 1024K
       minextents 1
       maxextents unlimited
   )
   logging
   tablespace DEVELOP_TABSPACE
)
pctfree 10
initrans 1
storage
(
    initial 64K
    next 1024K
    minextents 1
    maxextents unlimited
)
tablespace DEVELOP_TABSPACE
logging
 nocompress
 lob
 (DESCRIPCION)
    store as
         basicfile
 (tablespace DEVELOP_TABSPACE
        chunk 8192
 retention nocache);

drop table DEVELOP.SEQUENCE cascade constraints;

/*==============================================================*/
/* Table: SEQUENCE                                              */
/*==============================================================*/
create table DEVELOP.SEQUENCE
(
   SEQ_NAME             VARCHAR2(50)         not null,
   SEQ_COUNT            NUMBER,
   constraint SYS_C007263 primary key (SEQ_NAME)
         using index pctfree 10
   initrans 2
   storage
   (
       initial 64K
       next 1024K
       minextents 1
       maxextents unlimited
   )
   logging
   tablespace DEVELOP_TABSPACE
)
pctfree 10
initrans 1
storage
(
    initial 64K
    next 1024K
    minextents 1
    maxextents unlimited
)
tablespace DEVELOP_TABSPACE
logging
 nocompress
 monitoring
 noparallel;

JPA_2_SimpleTable


@Entity
public class Tabla implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator="TABLA_SEQ")
    @Column(name="TABLA_ID")
    private Long id;
    private String nombre;


drop table DEVELOP.TABLA cascade constraints;

/*==============================================================*/
/* Table: TABLA                                                 */
/*==============================================================*/
create table DEVELOP.TABLA
(
   TABLA_ID             NUMBER(19)           not null,
   APELLIDO             VARCHAR2(255),
   DESCRIPCION          CLOB,
   NOMBRE               VARCHAR2(255),
   EMP_PIC              BLOB                 not null,
   SQLDATE              DATE,
   SQLTIME              TIMESTAMP,
   SQLTIMESTAMP         TIMESTAMP,
   UTILDATE             DATE,
   VALDOUBLE            NUMBER(19,4),
   VALINTEGER           NUMBER(10),
   VALBOOLEAN           NUMBER(1)            default 0,
   constraint SYS_C007266 primary key (TABLA_ID)
         using index pctfree 10
   initrans 2
   storage
   (
       initial 64K
       next 1024K
       minextents 1
       maxextents unlimited
   )
   logging
   tablespace DEVELOP_TABSPACE
)
pctfree 10
initrans 1
storage
(
    initial 64K
    next 1024K
    minextents 1
    maxextents unlimited
)
tablespace DEVELOP_TABSPACE
logging
 nocompress
 lob
 (DESCRIPCION)
    store as
         basicfile
 (tablespace DEVELOP_TABSPACE
        chunk 8192
 retention nocache);

JPA_3_SimpleTable


@Entity
public class Tabla implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE, generator="TABLA_GEN")
    @Column(name="TABLA_ID")
    private Long id;
    private String nombre;


drop table DEVELOP.TABLA cascade constraints;

/*==============================================================*/
/* Table: TABLA                                                 */
/*==============================================================*/
create table DEVELOP.TABLA
(
   TABLA_ID             NUMBER(19)           not null,
   APELLIDO             VARCHAR2(255),
   DESCRIPCION          CLOB,
   NOMBRE               VARCHAR2(255),
   EMP_PIC              BLOB                 not null,
   SQLDATE              DATE,
   SQLTIME              TIMESTAMP,
   SQLTIMESTAMP         TIMESTAMP,
   UTILDATE             DATE,
   VALDOUBLE            NUMBER(19,4),
   VALINTEGER           NUMBER(10),
   VALBOOLEAN           NUMBER(1)            default 0,
   constraint SYS_C007269 primary key (TABLA_ID)
         using index pctfree 10
   initrans 2
   storage
   (
       initial 64K
       next 1024K
       minextents 1
       maxextents unlimited
   )
   logging
   tablespace DEVELOP_TABSPACE
)
pctfree 10
initrans 1
storage
(
    initial 64K
    next 1024K
    minextents 1
    maxextents unlimited
)
tablespace DEVELOP_TABSPACE
logging
 nocompress
 lob
 (DESCRIPCION)
    store as
         basicfile
 (tablespace DEVELOP_TABSPACE
        chunk 8192
 retention nocache);

drop table DEVELOP.SEQUENCE cascade constraints;

/*==============================================================*/
/* Table: SEQUENCE                                              */
/*==============================================================*/
create table DEVELOP.SEQUENCE
(
   SEQ_NAME             VARCHAR2(50)         not null,
   SEQ_COUNT            NUMBER,
   constraint SYS_C007271 primary key (SEQ_NAME)
         using index pctfree 10
   initrans 2
   storage
   (
       initial 64K
       next 1024K
       minextents 1
       maxextents unlimited
   )
   logging
   tablespace DEVELOP_TABSPACE
)
pctfree 10
initrans 1
storage
(
    initial 64K
    next 1024K
    minextents 1
    maxextents unlimited
)
tablespace DEVELOP_TABSPACE
logging
 nocompress
 monitoring
 noparallel;

JPA_4_SimpleTableElemColl


@Entity
public class Tabla implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE, generator="TABLA_GEN")
    @Column(name="TABLA_ID")
    private Long id;
    private String nombre;
    private String apellido;
    private Double valDouble;
    private Integer valInteger;
    private boolean valboolean;
    @Temporal(DATE)
    private java.util.Date utilDate;
    private java.sql.Date sqlDate;
    private Time sqlTime;
    private Timestamp sqlTimeStamp;
    @Lob
    private String descripcion;
    @Lob
    @Column(name="EMP_PIC",columnDefinition="BLOB NOT NULL")
    //@Column(name="EMP_PIC",columnDefinition="LONGBLOB NOT NULL") //en caso de MySQL
    private byte[] pic;
    @ElementCollection  //uses default table TABLA_ELEMCOLL
    @Column(name="DetalleTabla", length=50)
    private Set<String> ElemColl = new HashSet();


drop table DEVELOP.TABLA cascade constraints;

/*==============================================================*/
/* Table: TABLA                                                 */
/*==============================================================*/
create table DEVELOP.TABLA
(
   TABLA_ID             NUMBER(19)           not null,
   APELLIDO             VARCHAR2(255),
   DESCRIPCION          CLOB,
   NOMBRE               VARCHAR2(255),
   EMP_PIC              BLOB                 not null,
   SQLDATE              DATE,
   SQLTIME              TIMESTAMP,
   SQLTIMESTAMP         TIMESTAMP,
   UTILDATE             DATE,
   VALDOUBLE            NUMBER(19,4),
   VALINTEGER           NUMBER(10),
   VALBOOLEAN           NUMBER(1)            default 0,
   constraint SYS_C006999 primary key (TABLA_ID)
         using index pctfree 10
   initrans 2
   storage
   (
       initial 64K
       next 1024K
       minextents 1
       maxextents unlimited
   )
   logging
   tablespace DEVELOP_TABSPACE
)
pctfree 10
initrans 1
storage
(
    initial 64K
    next 1024K
    minextents 1
    maxextents unlimited
)
tablespace DEVELOP_TABSPACE
logging
 nocompress
 lob
 (DESCRIPCION)
    store as
         basicfile
 (tablespace DEVELOP_TABSPACE
        chunk 8192
 retention nocache);

alter table DEVELOP.TABLA_ELEMCOLL
   drop constraint TABLA_ELEMCOLL_TABLA_TABLA_ID;

drop table DEVELOP.TABLA_ELEMCOLL cascade constraints;

/*==============================================================*/
/* Table: TABLA_ELEMCOLL                                        */
/*==============================================================*/
create table DEVELOP.TABLA_ELEMCOLL
(
   TABLA_TABLA_ID       NUMBER(19),
   DETALLETABLA         VARCHAR2(50)
)
pctfree 10
initrans 1
storage
(
    initial 64K
    next 1024K
    minextents 1
    maxextents unlimited
)
tablespace DEVELOP_TABSPACE
logging
 nocompress
 monitoring
 noparallel;

alter table DEVELOP.TABLA_ELEMCOLL
   add constraint TABLA_ELEMCOLL_TABLA_TABLA_ID foreign key (TABLA_TABLA_ID)
      references DEVELOP.TABLA (TABLA_ID)
      not deferrable;

drop table DEVELOP.SEQUENCE cascade constraints;

/*==============================================================*/
/* Table: SEQUENCE                                              */
/*==============================================================*/
create table DEVELOP.SEQUENCE
(
   SEQ_NAME             VARCHAR2(50)         not null,
   SEQ_COUNT            NUMBER,
   constraint SYS_C007002 primary key (SEQ_NAME)
         using index pctfree 10
   initrans 2
   storage
   (
       initial 64K
       next 1024K
       minextents 1
       maxextents unlimited
   )
   logging
   tablespace DEVELOP_TABSPACE
)
pctfree 10
initrans 1
storage
(
    initial 64K
    next 1024K
    minextents 1
    maxextents unlimited
)
tablespace DEVELOP_TABSPACE
logging
 nocompress
 monitoring
 noparallel;

En caso de MySQL

drop table if exists wsp.tabla;

/*==============================================================*/
/* Table: tabla                                                 */
/*==============================================================*/
create table wsp.tabla
(
   TABLA_ID             bigint(20) not null,
   APELLIDO             national varchar(255),
   DESCRIPCION          national longtext,
   NOMBRE               national varchar(255),
   EMP_PIC              longblob not null,
   SQLDATE              date,
   SQLTIME              time,
   SQLTIMESTAMP         datetime,
   UTILDATE             date,
   VALDOUBLE            double,
   VALINTEGER           int(11),
   VALBOOLEAN           tinyint(1) default 0,
   primary key (TABLA_ID)
);

drop table if exists wsp.tabla_elemcoll;

/*==============================================================*/
/* Table: tabla_elemcoll                                        */
/*==============================================================*/
create table wsp.tabla_elemcoll
(
   Tabla_TABLA_ID       bigint(20),
   DetalleTabla         national varchar(50)
);

alter table wsp.tabla_elemcoll add constraint FK_Tabla_ELEMCOLL_Tabla_TABLA_ID foreign key (Tabla_TABLA_ID)
      references wsp.tabla (TABLA_ID);

drop table if exists wsp.sequence;

/*==============================================================*/
/* Table: sequence                                              */
/*==============================================================*/
create table wsp.sequence
(
   SEQ_NAME             national varchar(50) not null,
   SEQ_COUNT            decimal(38,0),
   primary key (SEQ_NAME)
);

JPA Relationships


ManyToOne Mappings


Employee(Many)   Department(One)

@Entity
public class Employee implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
    private Long salary;
    @ManyToOne
    private Department department;
   
}

@Entity
public class Department implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
   
}

DB scripts from Entity classes…

CREATE TABLE EMPLOYEE (ID NUMBER(19) NOT NULL, NAME VARCHAR2(255) NULL, SALARY NUMBER(19) NULL, DEPARTMENT_ID NUMBER(19) NULL, PRIMARY KEY (ID))
CREATE TABLE DEPARTMENT (ID NUMBER(19) NOT NULL, NAME VARCHAR2(255) NULL, PRIMARY KEY (ID))
ALTER TABLE EMPLOYEE ADD CONSTRAINT FK_EMPLOYEE_DEPARTMENT_ID FOREIGN KEY (DEPARTMENT_ID) REFERENCES DEPARTMENT (ID)
CREATE TABLE SEQUENCE (SEQ_NAME VARCHAR2(50) NOT NULL, SEQ_COUNT NUMBER(38) NULL, PRIMARY KEY (SEQ_NAME))
INSERT INTO SEQUENCE(SEQ_NAME, SEQ_COUNT) values ('SEQ_GEN', 0)


ManyToOne JoinColumn


@Entity
public class Employee implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
    private Long salary;
    @ManyToOne
    @JoinColumn(name="DEPT_ID")
    private Department department;
   
}

@Entity
public class Department implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
   
}

CREATE TABLE EMPLOYEE (ID NUMBER(19) NOT NULL, NAME VARCHAR2(255) NULL, SALARY NUMBER(19) NULL, DEPT_ID NUMBER(19) NULL, PRIMARY KEY (ID))
CREATE TABLE DEPARTMENT (ID NUMBER(19) NOT NULL, NAME VARCHAR2(255) NULL, PRIMARY KEY (ID))
ALTER TABLE EMPLOYEE ADD CONSTRAINT FK_EMPLOYEE_DEPT_ID FOREIGN KEY (DEPT_ID) REFERENCES DEPARTMENT (ID)
CREATE TABLE SEQUENCE (SEQ_NAME VARCHAR2(50) NOT NULL, SEQ_COUNT NUMBER(38) NULL, PRIMARY KEY (SEQ_NAME))
INSERT INTO SEQUENCE(SEQ_NAME, SEQ_COUNT) values ('SEQ_GEN', 0)


OneToOne Mappings


Employee (one) --- ParkingSpace (one)
@Entity
public class Employee implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
    private Long salary;
    @OneToOne
    @JoinColumn(name="PSPACE_ID")
    private ParkingSpace parkingSpace;
   
}

@Entity
public class ParkingSpace implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private int lot;
    private String location;
   
}

CREATE TABLE EMPLOYEE (ID NUMBER(19) NOT NULL, NAME VARCHAR2(255) NULL, SALARY NUMBER(19) NULL, PSPACE_ID NUMBER(19) NULL, PRIMARY KEY (ID))
CREATE TABLE PARKINGSPACE (ID NUMBER(19) NOT NULL, LOCATION VARCHAR2(255) NULL, LOT NUMBER(10) NULL, PRIMARY KEY (ID))
ALTER TABLE EMPLOYEE ADD CONSTRAINT FK_EMPLOYEE_PSPACE_ID FOREIGN KEY (PSPACE_ID) REFERENCES PARKINGSPACE (ID)
CREATE TABLE SEQUENCE (SEQ_NAME VARCHAR2(50) NOT NULL, SEQ_COUNT NUMBER(38) NULL, PRIMARY KEY (SEQ_NAME))
INSERT INTO SEQUENCE(SEQ_NAME, SEQ_COUNT) values ('SEQ_GEN', 0)

Check that the foreing key must have a uniqueness constraint, and it doesn’t happen. So in case of MySQL is added manually the constraint
ALTER TABLE EMPLOYEE ADD UNIQUE PARKINGSPACECONSTRAINT (DEPT_ID);
In Oracle
ALTER TABLE EMPLOYEE ADD CONTRAINT PARKINGSPACECONSTRAINT UNIQUE (DEPT_ID)
When populate with data test report an error of duplicates.

OneToOne Bidirectional


@Entity
public class Employee implements Serializable { 
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
    private Long salary;
    @OneToOne
    @JoinColumn(name="PSPACE_ID")
    private ParkingSpace parkingSpace;

@Entity
public class ParkingSpace implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private int lot;
    private String location;
    @OneToOne(mappedBy="parkingSpace")
    private Employee employee;

CREATE TABLE EMPLOYEE (ID NUMBER(19) NOT NULL, NAME VARCHAR2(255) NULL, SALARY NUMBER(19) NULL, PSPACE_ID NUMBER(19) NULL, PRIMARY KEY (ID))
CREATE TABLE PARKINGSPACE (ID NUMBER(19) NOT NULL, LOCATION VARCHAR2(255) NULL, LOT NUMBER(10) NULL, PRIMARY KEY (ID))
ALTER TABLE EMPLOYEE ADD CONSTRAINT FK_EMPLOYEE_PSPACE_ID FOREIGN KEY (PSPACE_ID) REFERENCES PARKINGSPACE (ID)
CREATE TABLE SEQUENCE (SEQ_NAME VARCHAR2(50) NOT NULL, SEQ_COUNT NUMBER(38) NULL, PRIMARY KEY (SEQ_NAME))
INSERT INTO SEQUENCE(SEQ_NAME, SEQ_COUNT) values ('SEQ_GEN', 0)

The generated script is the same as the OneToOne unidirection relation???

OneToMany


Employee (many) ---- Department (one)
@Entity
public class Employee implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
    private Long salary;
    private Department department;
   
}

@Entity
public class Department implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
    @OneToMany(cascade=CascadeType.PERSIST,mappedBy="department") //(fetch=FetchType.LAZY, cascade=CascadeType.PERSIST)
    private List<Employee> employees = new ArrayList<Employee>();
    
}

Script generated for MySQL:
CREATE TABLE EMPLOYEE (ID BIGINT NOT NULL, NAME VARCHAR(255), SALARY BIGINT, DEPARTMENT_ID BIGINT, PRIMARY KEY (ID))
CREATE TABLE DEPARTMENT (ID BIGINT NOT NULL, NAME VARCHAR(255), PRIMARY KEY (ID))
ALTER TABLE EMPLOYEE ADD CONSTRAINT FK_EMPLOYEE_DEPARTMENT_ID FOREIGN KEY (DEPARTMENT_ID) REFERENCES DEPARTMENT (ID)
CREATE TABLE SEQUENCE (SEQ_NAME VARCHAR(50) NOT NULL, SEQ_COUNT DECIMAL(38), PRIMARY KEY (SEQ_NAME))
INSERT INTO SEQUENCE(SEQ_NAME, SEQ_COUNT) values ('SEQ_GEN', 0)

OneToMany Version 2


@Entity
public class Employee implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE,generator="EMPLOYEE_GEN")
    @Column(name="EMP_ID")
    private Long id;
    private String name;
    private Long salary;
    @ManyToOne(targetEntity=Department.class, fetch=FetchType.LAZY)
    private Department department;
   
}

@Entity
public class Department implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE,generator="DEPARTMENT_GEN")
    @Column(name="DEP_ID")
    private Long id;
    private String name;
    @OneToMany(cascade=CascadeType.ALL,mappedBy="department") //(fetch=FetchType.LAZY, cascade=CascadeType.PERSIST)
    private List<Employee> employees = new ArrayList<Employee>();
    
}

MySQL script:


ManyToMany with out CascadeType.Persist


@Entity
public class Employee implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    //@GeneratedValue(strategy = GenerationType.TABLE,generator="EMP_TAB")
    //@TableGenerator(name="EMP_TAB",table="EMP_GEN")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="EMP_ID")
    private Long id;
    private String name;
    private Long salary;
    @ManyToMany//(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinTable(name="EMP_PROJ",
            joinColumns=@JoinColumn(name="EMP_ID"),
            inverseJoinColumns=@JoinColumn(name="PROJ_ID"))
    private List<Project> projects = new ArrayList<Project>();
  
}

@Entity
public class Project implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    //@GeneratedValue(strategy = GenerationType.TABLE,generator="PROJ_TAB")
    //@TableGenerator(name="PROJ_TAB",table="PROJ_GEN")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="PROJ_ID")
    private Long id;
    private String name;
    @ManyToMany(mappedBy="projects")
    private List<Employee> employees = new ArrayList<Employee>();
   
}

public class Populate {

    public static void main(String... args) {
        EntityManagerFactory emf = createEntityManagerFactory("JPArelationshipsPU");
        EntityManager em = emf.createEntityManager();
        populate(emf);
        emf.close();
    }
   
    private static void populate(EntityManagerFactory emf) {
        EntityManager em = emf.createEntityManager();
       
        Employee emp = new Employee();
        emp.setName("Un Empleado");
        emp.setSalary(1203L);
       
        Employee emp2 = new Employee();
        emp2.setName("Empleado Dos");
        emp2.setSalary(77777L);
       
        Employee emp3 = new Employee();
        emp3.setName("Empleado sin Departamento");
        emp3.setSalary(9999L);
              
        Project proj = new Project();
        proj.setName("Projecto ONE");
       
        Project proj2 = new Project();
        proj2.setName("Projecto X");
              
        emp.getProjects().add(proj);
        emp.getProjects().add(proj2);
       
        emp2.getProjects().add(proj2);
       
        proj.getEmployees().add(emp2);
        proj2.getEmployees().add(emp);
       
        em.getTransaction().begin();
        em.persist(emp);
        em.persist(emp2);
        em.persist(proj);          // Without PERSIST this is necesary
        em.persist(proj2);       // Withoiut PERSIST this is necesary
        em.getTransaction().commit();
        //em.flush();  
        em.close();
    }



If only is PERSISTED the employee with out CascadeType.PERSIST and not is PERSISTED the project the following error will throws:
[EL Warning]: java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: org.jamr.model.Project[ id=null ].
Exception in thread "main" javax.persistence.RollbackException: java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: org.jamr.model.Project[ id=null ].
                at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:157)
                at com.jamr.example.Populate.populate(Populate.java:63)
                at com.jamr.example.Populate.main(Populate.java:25)
Caused by: java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: org.jamr.model.Project[ id=null ].
                at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.discoverUnregisteredNewObjects(RepeatableWriteUnitOfWork.java:310)
                at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.calculateChanges(UnitOfWorkImpl.java:723)
                at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1516)
                at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:277)
                at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1169)
                at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:132)
                ... 2 more

Otherwise with employee with CascadeType.PERSIST, is not necessary Persist de project. Is automatically persisted by his relationship marked with employee.