/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.annotations;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import java.util.EnumSet;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.TimeZone;
import javax.persistence.PersistenceException;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.StaleStateException;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataBuilder;
import org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl;
import org.hibernate.dialect.Oracle10gDialect;
import org.hibernate.query.Query;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.schema.TargetType;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.testing.SkipForDialect;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
/**
* @author Emmanuel Bernard
*/
public class EntityTest extends BaseNonConfigCoreFunctionalTestCase {
private DateFormat df = SimpleDateFormat.getDateTimeInstance( DateFormat.LONG, DateFormat.LONG );
@Override
protected void configureMetadataBuilder(MetadataBuilder metadataBuilder) {
super.configureMetadataBuilder( metadataBuilder );
metadataBuilder.applyImplicitNamingStrategy( ImplicitNamingStrategyJpaCompliantImpl.INSTANCE );
}
@Test
public void testLoad() throws Exception {
//put an object in DB
assertEquals( "Flight", metadata().getEntityBinding( Flight.class.getName() ).getTable().getName() );
Session s = openSession();
Transaction tx = s.beginTransaction();
Flight firstOne = new Flight();
firstOne.setId( Long.valueOf( 1 ) );
firstOne.setName( "AF3202" );
firstOne.setDuration( new Long( 1000000 ) );
firstOne.setDurationInSec( 2000 );
s.save( firstOne );
s.flush();
tx.commit();
s.close();
//read it
s = openSession();
tx = s.beginTransaction();
firstOne = (Flight) s.get( Flight.class, Long.valueOf( 1 ) );
assertNotNull( firstOne );
assertEquals( Long.valueOf( 1 ), firstOne.getId() );
assertEquals( "AF3202", firstOne.getName() );
assertEquals( Long.valueOf( 1000000 ), firstOne.getDuration() );
assertFalse( "Transient is not working", 2000l == firstOne.getDurationInSec() );
tx.commit();
s.close();
}
@Test
public void testColumn() throws Exception {
//put an object in DB
Session s = openSession();
Transaction tx = s.beginTransaction();
Flight firstOne = new Flight();
firstOne.setId( Long.valueOf( 1 ) );
firstOne.setName( "AF3202" );
firstOne.setDuration( Long.valueOf( 1000000 ) );
firstOne.setDurationInSec( 2000 );
s.save( firstOne );
s.flush();
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
firstOne = new Flight();
firstOne.setId( Long.valueOf( 1 ) );
firstOne.setName( null );
try {
s.save( firstOne );
tx.commit();
fail( "Name column should be not null" );
}
catch (HibernateException e) {
//fine
}
finally {
s.close();
}
//insert an object and check that name is not updatable
s = openSession();
tx = s.beginTransaction();
firstOne = new Flight();
firstOne.setId( Long.valueOf( 1 ) );
firstOne.setName( "AF3202" );
firstOne.setTriggeredData( "should not be insertable" );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
firstOne = (Flight) s.get( Flight.class, Long.valueOf( 1 ) );
assertNotNull( firstOne );
assertEquals( Long.valueOf( 1 ), firstOne.getId() );
assertEquals( "AF3202", firstOne.getName() );
assertFalse( "should not be insertable".equals( firstOne.getTriggeredData() ) );
firstOne.setName( "BA1234" );
firstOne.setTriggeredData( "should not be updatable" );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
firstOne = (Flight) s.get( Flight.class, Long.valueOf( 1 ) );
assertNotNull( firstOne );
assertEquals( Long.valueOf( 1 ), firstOne.getId() );
assertEquals( "AF3202", firstOne.getName() );
assertFalse( "should not be updatable".equals( firstOne.getTriggeredData() ) );
tx.commit();
s.close();
}
@Test
public void testColumnUnique() throws Exception {
Session s;
Transaction tx;
s = openSession();
tx = s.beginTransaction();
Sky sky = new Sky();
sky.id = Long.valueOf( 2 );
sky.color = "blue";
sky.day = "monday";
sky.month = "January";
Sky sameSky = new Sky();
sameSky.id = Long.valueOf( 3 );
sameSky.color = "blue";
sky.day = "tuesday";
sky.month = "January";
try {
s.save( sky );
s.flush();
s.save( sameSky );
tx.commit();
fail( "unique constraints not respected" );
}
catch (HibernateException e) {
//success
}
finally {
if ( tx != null ) {
tx.rollback();
}
s.close();
}
}
@Test
public void testUniqueConstraint() throws Exception {
int id = 5;
Session s;
Transaction tx;
s = openSession();
tx = s.beginTransaction();
Sky sky = new Sky();
sky.id = Long.valueOf( id++ );
sky.color = "green";
sky.day = "monday";
sky.month = "March";
Sky otherSky = new Sky();
otherSky.id = Long.valueOf( id++ );
otherSky.color = "red";
otherSky.day = "friday";
otherSky.month = "March";
Sky sameSky = new Sky();
sameSky.id = Long.valueOf( id++ );
sameSky.color = "green";
sameSky.day = "monday";
sameSky.month = "March";
s.save( sky );
s.flush();
s.save( otherSky );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
try {
s.save( sameSky );
tx.commit();
fail( "unique constraints not respected" );
}
catch (PersistenceException e) {
//success
if ( tx != null ) {
tx.rollback();
}
}
finally {
s.close();
}
}
@Test
public void testVersion() throws Exception {
// put an object in DB
Session s = openSession();
Transaction tx = s.beginTransaction();
Flight firstOne = new Flight();
firstOne.setId( Long.valueOf( 2 ) );
firstOne.setName( "AF3202" );
firstOne.setDuration( Long.valueOf( 500 ) );
s.save( firstOne );
s.flush();
tx.commit();
s.close();
//read it
s = openSession();
tx = s.beginTransaction();
firstOne = (Flight) s.get( Flight.class, Long.valueOf( 2 ) );
tx.commit();
s.close();
//read it again
s = openSession();
tx = s.beginTransaction();
Flight concurrentOne = (Flight) s.get( Flight.class, Long.valueOf( 2 ) );
concurrentOne.setDuration( Long.valueOf( 1000 ) );
s.update( concurrentOne );
tx.commit();
s.close();
assertFalse( firstOne == concurrentOne );
assertFalse( firstOne.getVersion().equals( concurrentOne.getVersion() ) );
//reattach the first one
s = openSession();
tx = s.beginTransaction();
firstOne.setName( "Second access" );
s.update( firstOne );
try {
tx.commit();
fail( "Optimistic locking should work" );
}
catch (PersistenceException expected) {
if ( expected.getCause() instanceof StaleStateException ) {
//expected
}
else {
fail( "StaleStateException expected but is " + expected.getCause() );
}
}
finally {
if ( tx != null ) {
tx.rollback();
}
s.close();
}
}
@Test
public void testFieldAccess() throws Exception {
Session s;
Transaction tx;
s = openSession();
tx = s.beginTransaction();
Sky sky = new Sky();
sky.id = Long.valueOf( 1 );
sky.color = "black";
sky.area = "Paris";
sky.day = "23";
sky.month = "1";
s.save( sky );
tx.commit();
s.close();
sky.area = "London";
s = openSession();
tx = s.beginTransaction();
sky = (Sky) s.get( Sky.class, sky.id );
assertNotNull( sky );
assertEquals( "black", sky.color );
assertFalse( "Paris".equals( sky.area ) );
tx.commit();
s.close();
}
@Test
public void testEntityName() throws Exception {
assertEquals( "Corporation", metadata().getEntityBinding( Company.class.getName() ).getTable().getName() );
Session s = openSession();
Transaction tx = s.beginTransaction();
Company comp = new Company();
s.persist( comp );
comp.setName( "JBoss Inc" );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
List result = s.createQuery( "from Corporation" ).list();
assertNotNull( result );
assertEquals( 1, result.size() );
tx.commit();
s.close();
}
@Test
public void testNonGetter() throws Exception {
Session s = openSession();
Transaction tx = s.beginTransaction();
Flight airFrance = new Flight();
airFrance.setId( Long.valueOf( 747 ) );
airFrance.setName( "Paris-Amsterdam" );
airFrance.setDuration( Long.valueOf( 10 ) );
airFrance.setFactor( 25 );
s.persist( airFrance );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
airFrance = (Flight) s.get( Flight.class, airFrance.getId() );
assertNotNull( airFrance );
assertEquals( Long.valueOf( 10 ), airFrance.getDuration() );
assertFalse( 25 == airFrance.getFactor( false ) );
s.delete( airFrance );
tx.commit();
s.close();
}
@Test
@SkipForDialect(value = Oracle10gDialect.class, comment = "oracle12c returns time in getDate. For now, skip.")
public void testTemporalType() throws Exception {
Flight airFrance = doInHibernate( this::sessionFactory, session -> {
Flight _airFrance = new Flight();
_airFrance.setId( Long.valueOf( 747 ) );
_airFrance.setName( "Paris-Amsterdam" );
_airFrance.setDuration( Long.valueOf( 10 ) );
_airFrance.setDepartureDate( Date.from(LocalDate.of( 2005, 06, 21 ).atStartOfDay(
ZoneId.systemDefault()).toInstant()) );
_airFrance.setAlternativeDepartureDate( new GregorianCalendar( 2006, 02, 03, 10, 00 ) );
_airFrance.getAlternativeDepartureDate().setTimeZone( TimeZone.getTimeZone( "GMT" ) );
_airFrance.setBuyDate( new java.sql.Timestamp( 122367443 ) );
_airFrance.setFactor( 25 );
session.persist( _airFrance );
return _airFrance;
} );
doInHibernate( this::sessionFactory, session -> {
Query q = session.createQuery( "from Flight f where f.departureDate = :departureDate" );
q.setParameter( "departureDate", airFrance.getDepartureDate(), StandardBasicTypes.DATE );
Flight copyAirFrance = (Flight) q.uniqueResult();
assertNotNull( copyAirFrance );
assertEquals(
Date.from(LocalDate.of( 2005, 06, 21 ).atStartOfDay(
ZoneId.systemDefault()).toInstant()),
copyAirFrance.getDepartureDate()
);
assertEquals( df.format( airFrance.getBuyDate() ), df.format( copyAirFrance.getBuyDate() ) );
session.delete( copyAirFrance );
} );
}
@Test
public void testBasic() throws Exception {
Session s = openSession();
Transaction tx = s.beginTransaction();
Flight airFrance = new Flight();
airFrance.setId( Long.valueOf( 747 ) );
airFrance.setName( "Paris-Amsterdam" );
airFrance.setDuration( null );
try {
s.persist( airFrance );
tx.commit();
fail( "Basic(optional=false) fails" );
}
catch (Exception e) {
//success
if ( tx != null ) {
tx.rollback();
}
}
finally {
s.close();
}
}
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] {
Flight.class,
Company.class,
Sky.class
};
}
// tests are leaving data around, so drop/recreate schema for now. this is wha the old tests did
@Override
protected boolean createSchema() {
return false;
}
@Before
public void runCreateSchema() {
new SchemaExport().create( EnumSet.of( TargetType.DATABASE ), metadata() );
}
@After
public void runDropSchema() {
new SchemaExport().drop( EnumSet.of( TargetType.DATABASE ), metadata() );
}
}