/* * 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() ); } }