Fix o.h.Interceptor#onSave call

This commit is contained in:
Andrea Boriero 2021-11-30 13:35:07 +01:00 committed by Andrea Boriero
parent 55db51894f
commit df0479951c
40 changed files with 321 additions and 256 deletions

View File

@ -9,6 +9,7 @@ package org.hibernate;
import java.io.Serializable;
import org.hibernate.metamodel.RepresentationMode;
import org.hibernate.type.Type;
/**
* An interceptor that does nothing. May be used as a base class for application-defined custom interceptors.
@ -26,6 +27,12 @@ public class EmptyInterceptor implements Interceptor, Serializable {
protected EmptyInterceptor() {}
@Override
public boolean onSave(Object entity, Object id, Object[] state, String[] propertyNames, Type[] types)
throws CallbackException {
return false;
}
@Override
public Object instantiate(String entityName, RepresentationMode representationMode, Object id) throws CallbackException {
return null;

View File

@ -168,36 +168,9 @@ public interface Interceptor {
* @return <tt>true</tt> if the user modified the <tt>state</tt> in any way.
*
* @throws CallbackException Thrown if the interceptor encounters any problems handling the callback.
*
* @deprecated use {@link #onSave(Object, Object, Object[], String[], Type[])}
*/
@Deprecated
default boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types)
throws CallbackException {
return false;
}
/**
* Called before an object is saved. The interceptor may modify the <tt>state</tt>, which will be used for
* the SQL <tt>INSERT</tt> and propagated to the persistent object.
*
* @param entity The entity instance whose state is being inserted
* @param id The identifier of the entity
* @param state The state of the entity which will be inserted
* @param propertyNames The names of the entity properties.
* @param types The types of the entity properties
*
* @return <tt>true</tt> if the user modified the <tt>state</tt> in any way.
*
* @throws CallbackException Thrown if the interceptor encounters any problems handling the callback.
*/
default boolean onSave(Object entity, Object id, Object[] state, String[] propertyNames, Type[] types)
throws CallbackException {
if (id instanceof Serializable) {
return onSave(entity, (Serializable) id, state, propertyNames, types);
}
return false;
}
boolean onSave(Object entity, Object id, Object[] state, String[] propertyNames, Type[] types)
throws CallbackException;
/**
* Called before an object is deleted. It is not recommended that the interceptor modify the <tt>state</tt>.

View File

@ -4,24 +4,26 @@
* 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.component.empty;
package org.hibernate.orm.test.component.empty;
import org.hibernate.cfg.Environment;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.testing.orm.junit.Setting;
import org.junit.jupiter.api.Test;
import jakarta.persistence.Embeddable;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.orm.test.component.empty.ComponentEmptyEmbedded;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import org.hibernate.testing.FailureExpected;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;
import static org.junit.Assert.assertNotNull;
/**
* Tests that an empty embeddable that is nested inside an embeddable is initialized.
@ -29,46 +31,45 @@ import static org.junit.Assert.assertNotNull;
* @author Gail Badner
*/
@TestForIssue(jiraKey = "HHH-11926")
public class EmptyInitializedNestedCompositesTest extends BaseCoreFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] { ComponentEmptyNestedEmbeddedOwner.class };
}
@Override
protected void configure(Configuration configuration) {
super.configure( configuration );
configuration.getProperties().put( Environment.CREATE_EMPTY_COMPOSITES_ENABLED, Boolean.valueOf( true ) );
}
@DomainModel(
annotatedClasses = EmptyInitializedNestedCompositesTest.ComponentEmptyNestedEmbeddedOwner.class
)
@SessionFactory
@ServiceRegistry(
settings = @Setting(name = Environment.CREATE_EMPTY_COMPOSITES_ENABLED, value = "true")
)
public class EmptyInitializedNestedCompositesTest {
/**
* Test empty nested composite initialization.
*/
@Test
@FailureExpected( jiraKey = "HHH-11926" )
public void testCompositesEmpty() {
Session s = openSession();
try {
s.getTransaction().begin();
public void testCompositesEmpty(SessionFactoryScope scope) {
ComponentEmptyNestedEmbeddedOwner owner = new ComponentEmptyNestedEmbeddedOwner();
s.persist( owner );
scope.inSession(
session -> {
session.beginTransaction();
try {
ComponentEmptyNestedEmbeddedOwner owner = new ComponentEmptyNestedEmbeddedOwner();
session.persist( owner );
s.flush();
s.getTransaction().commit();
session.flush();
session.getTransaction().commit();
s.clear();
s.getTransaction().begin();
owner = s.get( ComponentEmptyNestedEmbeddedOwner.class, owner.getId() );
assertNotNull( owner.getEmbedded() );
assertNotNull( owner.getEmbedded().getNestedEmbedded() );
s.getTransaction().rollback();
}
finally {
s.close();
}
session.clear();
session.getTransaction().begin();
owner = session.get( ComponentEmptyNestedEmbeddedOwner.class, owner.getId() );
assertNotNull( owner.getEmbedded() );
assertNotNull( owner.getEmbedded().getNestedEmbedded() );
session.getTransaction().commit();
}
finally {
if ( session.getTransaction().isActive() ) {
session.getTransaction().rollback();
}
}
}
);
}
@Entity(name = "EmptyNestedOwner")

View File

@ -6,7 +6,7 @@
*/
//$Id: CollectionInterceptor.java 7700 2005-07-30 05:02:47Z oneovthafew $
package org.hibernate.test.interceptor;
package org.hibernate.orm.test.interceptor;
import java.io.Serializable;
import org.hibernate.EmptyInterceptor;
@ -19,7 +19,7 @@ public class CollectionInterceptor extends EmptyInterceptor {
return false;
}
public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
public boolean onSave(Object entity, Object id, Object[] state, String[] propertyNames, Type[] types) {
( (User) entity ).getActions().add("created");
return false;
}

View File

@ -9,7 +9,7 @@
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="org.hibernate.test.interceptor">
<hibernate-mapping package="org.hibernate.orm.test.interceptor">
<class name="Image" table="image" abstract="false" select-before-update="true" >
<id name="id" type="java.lang.Long" column="id">

View File

@ -4,7 +4,7 @@
* 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.interceptor;
package org.hibernate.orm.test.interceptor;
public class Image {

View File

@ -8,7 +8,7 @@
/**
* @author Gail Badner
*/
package org.hibernate.test.interceptor;
package org.hibernate.orm.test.interceptor;
import org.hibernate.CallbackException;
import org.hibernate.EmptyInterceptor;
@ -23,7 +23,7 @@ public class InstantiateInterceptor extends EmptyInterceptor {
@Override
public Object instantiate(String entityName, RepresentationMode entityMode, Object id) throws CallbackException {
if ( ! "org.hibernate.test.interceptor.User".equals( entityName ) ) {
if ( ! "org.hibernate.orm.test.interceptor.User".equals( entityName ) ) {
return null;
}
// Simply inject a sample string into new instances

View File

@ -4,7 +4,7 @@
* 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.interceptor;
package org.hibernate.orm.test.interceptor;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;

View File

@ -4,10 +4,12 @@
* 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.interceptor;
package org.hibernate.orm.test.interceptor;
import jakarta.persistence.PersistenceException;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;
@ -22,8 +24,10 @@ import org.hibernate.Interceptor;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.TransactionException;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.hibernate.type.Type;
import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
@ -44,21 +48,26 @@ public class InterceptorTest extends BaseCoreFunctionalTestCase {
return new String[] { "interceptor/User.hbm.xml", "interceptor/Image.hbm.xml" };
}
@Override
protected String getBaseForMappings() {
return "org/hibernate/orm/test/";
}
@Test
public void testCollectionIntercept() {
Session s = openSession( new CollectionInterceptor() );
Transaction t = s.beginTransaction();
User u = new User("Gavin", "nivag");
s.persist(u);
u.setPassword("vagni");
User u = new User( "Gavin", "nivag" );
s.persist( u );
u.setPassword( "vagni" );
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
u = (User) s.get(User.class, "Gavin");
u = s.get( User.class, "Gavin" );
assertEquals( 2, u.getActions().size() );
s.delete(u);
s.delete( u );
t.commit();
s.close();
}
@ -67,18 +76,18 @@ public class InterceptorTest extends BaseCoreFunctionalTestCase {
public void testPropertyIntercept() {
Session s = openSession( new PropertyInterceptor() );
Transaction t = s.beginTransaction();
User u = new User("Gavin", "nivag");
s.persist(u);
u.setPassword("vagni");
User u = new User( "Gavin", "nivag" );
s.persist( u );
u.setPassword( "vagni" );
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
u = (User) s.get(User.class, "Gavin");
u = s.get( User.class, "Gavin" );
assertNotNull( u.getCreated() );
assertNotNull( u.getLastUpdated() );
s.delete(u);
s.delete( u );
t.commit();
s.close();
}
@ -89,34 +98,46 @@ public class InterceptorTest extends BaseCoreFunctionalTestCase {
* causes EntityPersister.findDirty() to return no dirty properties.
*/
@Test
@TestForIssue( jiraKey = "HHH-1921" )
@TestForIssue(jiraKey = "HHH-1921")
public void testPropertyIntercept2() {
Session s = openSession();
Transaction t = s.beginTransaction();
User u = new User("Josh", "test");
User u = new User( "Josh", "test" );
s.persist( u );
t.commit();
s.close();
s = openSession(
new EmptyInterceptor() {
public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) {
currentState[0] = "test";
@Override
public boolean onFlushDirty(
Object entity,
Serializable id,
Object[] currentState,
Object[] previousState,
String[] propertyNames,
Type[] types) {
for ( int i = 0; i < propertyNames.length; i++ ) {
if ( propertyNames[i].equals( "password" ) ) {
currentState[i] = "test";
}
}
return true;
}
}
);
t = s.beginTransaction();
u = ( User ) s.get( User.class, u.getName() );
u = s.get( User.class, u.getName() );
u.setPassword( "nottest" );
t.commit();
s.close();
s = openSession();
t = s.beginTransaction();
u = (User) s.get(User.class, "Josh");
assertEquals("test", u.getPassword());
s.delete(u);
u = s.get( User.class, "Josh" );
assertEquals( "test", u.getPassword() );
s.delete( u );
t.commit();
s.close();
@ -137,17 +158,17 @@ public class InterceptorTest extends BaseCoreFunctionalTestCase {
t.begin();
// Sleep for an amount of time that exceeds the transaction timeout
Thread.sleep( WAIT * 1000 );
try {
// Do something with the transaction and try to commit it
s.persist( new User( "john", "test" ) );
t.commit();
fail( "Transaction should have timed out" );
}
catch (PersistenceException e){
assertTyping(TransactionException.class, e.getCause());
try {
// Do something with the transaction and try to commit it
s.persist( new User( "john", "test" ) );
t.commit();
fail( "Transaction should have timed out" );
}
catch (PersistenceException e) {
assertTyping( TransactionException.class, e.getCause() );
assertTrue(
"Transaction failed for the wrong reason. Expecting transaction timeout, but found [" +
e.getCause().getMessage() + "]" ,
e.getCause().getMessage() + "]",
e.getCause().getMessage().contains( "transaction timeout expired" )
);
}
@ -160,7 +181,13 @@ public class InterceptorTest extends BaseCoreFunctionalTestCase {
Session s = openSession(
new EmptyInterceptor() {
public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
@Override
public boolean onSave(
Object entity,
Object id,
Object[] state,
String[] propertyNames,
Type[] types) {
if ( state[0] == null ) {
Image.Details detail = new Image.Details();
detail.setPerm1( checkPerm );
@ -174,7 +201,7 @@ public class InterceptorTest extends BaseCoreFunctionalTestCase {
s.beginTransaction();
Image i = new Image();
i.setName( "compincomp" );
i = ( Image ) s.merge( i );
i = (Image) s.merge( i );
assertNotNull( i.getDetails() );
assertEquals( checkPerm, i.getDetails().getPerm1() );
assertEquals( checkComment, i.getDetails().getComment() );
@ -183,7 +210,7 @@ public class InterceptorTest extends BaseCoreFunctionalTestCase {
s = openSession();
s.beginTransaction();
i = ( Image ) s.get( Image.class, i.getId() );
i = s.get( Image.class, i.getId() );
assertNotNull( i.getDetails() );
assertEquals( checkPerm, i.getDetails().getPerm1() );
assertEquals( checkComment, i.getDetails().getComment() );
@ -197,7 +224,7 @@ public class InterceptorTest extends BaseCoreFunctionalTestCase {
User u = new User( "Gavin", "nivag" );
final StatefulInterceptor statefulInterceptor = new StatefulInterceptor();
try(Session s = openSession( statefulInterceptor )) {
try (Session s = openSession( statefulInterceptor )) {
statefulInterceptor.setSession( s );
Transaction t = s.beginTransaction();
@ -222,7 +249,7 @@ public class InterceptorTest extends BaseCoreFunctionalTestCase {
List<Log> logs = s.createQuery( criteria ).list();
// List logs = s.createCriteria(Log.class).list();
assertEquals( 2, logs.size() );
s.delete(u);
s.delete( u );
s.createQuery( "delete from Log" ).executeUpdate();
}
@ -247,14 +274,14 @@ public class InterceptorTest extends BaseCoreFunctionalTestCase {
s = openSession( initiateInterceptor );
t = s.beginTransaction();
User merged = ( User ) s.merge( u );
User merged = (User) s.merge( u );
assertEquals( injectedString, merged.getInjectedString() );
assertEquals( u.getName(), merged.getName() );
assertEquals( u.getPassword(), merged.getPassword() );
merged.setInjectedString( null );
User loaded = ( User ) s.load(User.class, merged.getName());
User loaded = s.load( User.class, merged.getName() );
// the session-bound instance was not instantiated by the interceptor, load simply returns it
assertSame( merged, loaded );
assertNull( merged.getInjectedString() );
@ -263,7 +290,7 @@ public class InterceptorTest extends BaseCoreFunctionalTestCase {
s.flush();
s.evict( merged );
User reloaded = ( User ) s.load( User.class, merged.getName() );
User reloaded = s.load( User.class, merged.getName() );
// Interceptor IS called for instantiating the persistent instance associated to the session when using load
assertEquals( injectedString, reloaded.getInjectedString() );
assertEquals( u.getName(), reloaded.getName() );
@ -275,9 +302,9 @@ public class InterceptorTest extends BaseCoreFunctionalTestCase {
}
@Test
@TestForIssue( jiraKey = "HHH-6594" )
@TestForIssue(jiraKey = "HHH-6594")
public void testPrepareStatementIntercept() {
final Queue<String> expectedSQLs = new LinkedList<String>();
final Queue<String> expectedSQLs = new LinkedList<>();
// Transaction 1
expectedSQLs.add( "insert" );
// Transaction 2
@ -285,7 +312,7 @@ public class InterceptorTest extends BaseCoreFunctionalTestCase {
expectedSQLs.add( "select" );
// Transaction 3
expectedSQLs.add( "select" );
expectedSQLs.add( "select" );
// expectedSQLs.add( "select" );
expectedSQLs.add( "update" );
// Transaction 4
expectedSQLs.add( "select" );
@ -295,20 +322,23 @@ public class InterceptorTest extends BaseCoreFunctionalTestCase {
@Override
public String onPrepareStatement(String sql) {
assertNotNull( sql );
String expectedSql = expectedSQLs.poll().toLowerCase(Locale.ROOT);
assertTrue("sql:\n " + sql.toLowerCase(Locale.ROOT) +"\n doesn't start with \n"+expectedSql+"\n", sql.toLowerCase(Locale.ROOT).startsWith( expectedSql ) );
String expectedSql = expectedSQLs.poll().toLowerCase( Locale.ROOT );
assertTrue(
"sql:\n " + sql.toLowerCase( Locale.ROOT ) + "\n doesn't start with \n" + expectedSql + "\n",
sql.toLowerCase( Locale.ROOT ).startsWith( expectedSql )
);
return sql;
}
};
Session s = openSession(interceptor);
Session s = openSession( interceptor );
Transaction t = s.beginTransaction();
User u = new User( "Lukasz", "Antoniak" );
s.persist( u );
t.commit();
s.close();
s = openSession(interceptor);
s = openSession( interceptor );
t = s.beginTransaction();
s.get( User.class, "Lukasz" );
s.createQuery( "from User u" ).list();
@ -316,13 +346,13 @@ public class InterceptorTest extends BaseCoreFunctionalTestCase {
s.close();
u.setPassword( "Kinga" );
s = openSession(interceptor);
s = openSession( interceptor );
t = s.beginTransaction();
s.merge( u );
t.commit();
s.close();
s = openSession(interceptor);
s = openSession( interceptor );
t = s.beginTransaction();
s.delete( u );
t.commit();
@ -346,9 +376,11 @@ public class InterceptorTest extends BaseCoreFunctionalTestCase {
User u = new User( "Kinga", "Mroz" );
s.persist( u );
t.commit();
}catch (TransactionException e){
}
catch (TransactionException e) {
assertTrue( e.getCause() instanceof AssertionFailure );
}finally {
}
finally {
s.close();
}
}

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.hibernate.test.interceptor;
package org.hibernate.orm.test.interceptor;
import org.hibernate.EmptyInterceptor;
import org.hibernate.Interceptor;
@ -30,7 +30,7 @@ import static org.junit.Assert.assertTrue;
public class InterceptorTransactionEventTest extends BaseCoreFunctionalTestCase {
@Test
public void testTransactionEvents() throws Exception {
public void testTransactionEvents() {
LoggingInterceptor interceptor = new LoggingInterceptor();
Session s = openSession(interceptor);

View File

@ -6,7 +6,7 @@
*/
//$Id: Log.java 7700 2005-07-30 05:02:47Z oneovthafew $
package org.hibernate.test.interceptor;
package org.hibernate.orm.test.interceptor;
import java.util.Calendar;
public class Log {

View File

@ -6,7 +6,7 @@
*/
//$Id: PropertyInterceptor.java 7700 2005-07-30 05:02:47Z oneovthafew $
package org.hibernate.test.interceptor;
package org.hibernate.orm.test.interceptor;
import java.io.Serializable;
import java.util.Calendar;
@ -15,12 +15,14 @@ import org.hibernate.type.Type;
public class PropertyInterceptor extends EmptyInterceptor {
@Override
public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) {
currentState[1] = Calendar.getInstance();
return true;
}
public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
@Override
public boolean onSave(Object entity, Object id, Object[] state, String[] propertyNames, Type[] types) {
state[2] = Calendar.getInstance();
return true;
}

View File

@ -6,7 +6,7 @@
*/
//$Id: StatefulInterceptor.java 7701 2005-07-30 05:07:01Z oneovthafew $
package org.hibernate.test.interceptor;
package org.hibernate.orm.test.interceptor;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
@ -22,13 +22,15 @@ public class StatefulInterceptor extends EmptyInterceptor {
private List list = new ArrayList();
public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
@Override
public boolean onSave(Object entity, Object id, Object[] state, String[] propertyNames, Type[] types) {
if ( !(entity instanceof Log) ) {
list.add( new Log( "insert", (String) id, entity.getClass().getName() ) );
}
return false;
}
@Override
public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) {
if ( !(entity instanceof Log) ) {
list.add( new Log( "update", (String) id, entity.getClass().getName() ) );
@ -36,6 +38,7 @@ public class StatefulInterceptor extends EmptyInterceptor {
return false;
}
@Override
public void postFlush(Iterator entities) {
if ( list.size()>0 ) {
for ( Iterator iter = list.iterator(); iter.hasNext(); ) {

View File

@ -15,7 +15,7 @@
-->
<hibernate-mapping
package="org.hibernate.test.interceptor">
package="org.hibernate.orm.test.interceptor">
<class name="User" table="users">
<id name="name"/>

View File

@ -6,7 +6,7 @@
*/
//$Id: User.java 7700 2005-07-30 05:02:47Z oneovthafew $
package org.hibernate.test.interceptor;
package org.hibernate.orm.test.interceptor;
import java.util.Calendar;
import java.util.HashSet;
import java.util.Set;

View File

@ -6,7 +6,7 @@
*/
//$Id: Document.java 4407 2004-08-22 01:20:08Z oneovthafew $
package org.hibernate.test.interfaceproxy;
package org.hibernate.orm.test.interfaceproxy;
import java.sql.Blob;
import java.util.Calendar;

View File

@ -6,7 +6,7 @@
*/
//$Id: DocumentImpl.java 4407 2004-08-22 01:20:08Z oneovthafew $
package org.hibernate.test.interfaceproxy;
package org.hibernate.orm.test.interfaceproxy;
import java.sql.Blob;
import java.util.Calendar;

View File

@ -6,7 +6,7 @@
*/
//$Id: DocumentInterceptor.java 7860 2005-08-11 21:58:23Z oneovthafew $
package org.hibernate.test.interfaceproxy;
package org.hibernate.orm.test.interfaceproxy;
import java.io.Serializable;
import java.util.Calendar;
@ -40,7 +40,7 @@ public class DocumentInterceptor implements Interceptor {
}
}
public boolean onSave(Object entity, Serializable id, Object[] state,
public boolean onSave(Object entity, Object id, Object[] state,
String[] propertyNames, Type[] types) throws CallbackException {
if ( entity instanceof Document ) {
state[3] = state[2] = Calendar.getInstance();

View File

@ -6,7 +6,7 @@
*/
//$Id: Folder.java 4407 2004-08-22 01:20:08Z oneovthafew $
package org.hibernate.test.interfaceproxy;
package org.hibernate.orm.test.interfaceproxy;
/**

View File

@ -6,7 +6,7 @@
*/
//$Id: FolderImpl.java 4407 2004-08-22 01:20:08Z oneovthafew $
package org.hibernate.test.interfaceproxy;
package org.hibernate.orm.test.interfaceproxy;
/**

View File

@ -0,0 +1,122 @@
/*
* 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.orm.test.interfaceproxy;
import org.hibernate.Session;
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
/**
* @author Gavin King
*/
@DomainModel(
xmlMappings = { "org/hibernate/orm/test/interfaceproxy/Item.hbm.xml" }
)
@SessionFactory
public class InterfaceProxyTest {
@Test
@RequiresDialectFeature(
feature = DialectFeatureChecks.SupportsExpectedLobUsagePattern.class,
comment = "database/driver does not support expected LOB usage pattern"
)
public void testInterfaceProxies(SessionFactoryScope scope) {
Document doc = new DocumentImpl();
SecureDocument doc2 = new SecureDocumentImpl();
try (Session session = openSession( scope )) {
session.beginTransaction();
try {
doc.setName( "Hibernate in Action" );
doc.setContent( session.getLobHelper().createBlob( "blah blah blah".getBytes() ) );
session.save( doc );
doc2.setName( "Secret" );
doc2.setContent( session.getLobHelper().createBlob( "wxyz wxyz".getBytes() ) );
// SybaseASE15Dialect only allows 7-bits in a byte to be inserted into a tinyint
// column (0 <= val < 128)
doc2.setPermissionBits( (byte) 127 );
doc2.setOwner( "gavin" );
session.save( doc2 );
session.getTransaction().commit();
}
finally {
if ( session.getTransaction().isActive() ) {
session.getTransaction().rollback();
}
}
}
Long did = doc.getId();
Long d2id = doc2.getId();
try (Session session = openSession( scope )) {
session.beginTransaction();
try {
Document d = (Document) session.load( ItemImpl.class, did );
assertEquals( did, d.getId() );
assertEquals( "Hibernate in Action", d.getName() );
assertNotNull( d.getContent() );
SecureDocument d2 = (SecureDocument) session.load( ItemImpl.class, d2id );
assertEquals( d2id, d2.getId() );
assertEquals( "Secret", d2.getName() );
assertNotNull( d2.getContent() );
session.clear();
d = session.load( DocumentImpl.class, did );
assertEquals( did, d.getId() );
assertEquals( "Hibernate in Action", d.getName() );
assertNotNull( d.getContent() );
d2 = session.load( SecureDocumentImpl.class, d2id );
assertEquals( d2id, d2.getId() );
assertEquals( "Secret", d2.getName() );
assertNotNull( d2.getContent() );
assertEquals( "gavin", d2.getOwner() );
//s.clear();
d2 = session.load( SecureDocumentImpl.class, did );
assertEquals( did, d2.getId() );
assertEquals( "Hibernate in Action", d2.getName() );
assertNotNull( d2.getContent() );
try {
d2.getOwner(); //CCE
fail( "ClassCastException expected" );
}
catch (ClassCastException cce) {
//correct
}
session.createQuery( "delete ItemImpl" ).executeUpdate();
}
finally {
if ( session.getTransaction().isActive() ) {
session.getTransaction().rollback();
}
}
}
}
private Session openSession(SessionFactoryScope scope) {
return scope.getSessionFactory()
.withOptions()
.interceptor( new DocumentInterceptor() )
.openSession();
}
}

View File

@ -17,7 +17,7 @@
-->
<hibernate-mapping
package="org.hibernate.test.interfaceproxy">
package="org.hibernate.orm.test.interfaceproxy">
<class name="ItemImpl"
table="Items"

View File

@ -6,7 +6,7 @@
*/
//$Id: Item.java 4407 2004-08-22 01:20:08Z oneovthafew $
package org.hibernate.test.interfaceproxy;
package org.hibernate.orm.test.interfaceproxy;
/**

View File

@ -6,7 +6,7 @@
*/
//$Id: ItemImpl.java 4407 2004-08-22 01:20:08Z oneovthafew $
package org.hibernate.test.interfaceproxy;
package org.hibernate.orm.test.interfaceproxy;
/**

View File

@ -6,7 +6,7 @@
*/
//$Id: SecureDocument.java 4407 2004-08-22 01:20:08Z oneovthafew $
package org.hibernate.test.interfaceproxy;
package org.hibernate.orm.test.interfaceproxy;
/**

View File

@ -6,7 +6,7 @@
*/
//$Id: SecureDocumentImpl.java 4407 2004-08-22 01:20:08Z oneovthafew $
package org.hibernate.test.interfaceproxy;
package org.hibernate.orm.test.interfaceproxy;
/**

View File

@ -29,12 +29,14 @@ public class ExceptionInterceptor extends EmptyInterceptor {
this.allowSave = allowSave;
}
@Override
public boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types)
throws CallbackException {
throw new IllegalStateException( EXCEPTION_MESSAGE );
}
public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types)
@Override
public boolean onSave(Object entity, Object id, Object[] state, String[] propertyNames, Type[] types)
throws CallbackException {
if (allowSave) return false;
throw new IllegalStateException( EXCEPTION_MESSAGE );

View File

@ -19,7 +19,8 @@ import org.hibernate.type.Type;
public class LocalExceptionInterceptor extends ExceptionInterceptor {
public static final String LOCAL_EXCEPTION_MESSAGE = "Session-scoped interceptor enabled";
public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types)
@Override
public boolean onSave(Object entity, Object id, Object[] state, String[] propertyNames, Type[] types)
throws CallbackException {
if (allowSave) return false;
throw new IllegalStateException( LOCAL_EXCEPTION_MESSAGE );

View File

@ -4,7 +4,7 @@
* 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.proxy;
package org.hibernate.orm.test.proxy;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

View File

@ -10,7 +10,7 @@
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping
package="org.hibernate.test.proxy">
package="org.hibernate.orm.test.proxy">
<class name="DataPoint">
<id name="id">

View File

@ -6,7 +6,7 @@
*/
//$Id: DataPoint.java 10223 2006-08-04 20:29:21Z steve.ebersole@jboss.com $
package org.hibernate.test.proxy;
package org.hibernate.orm.test.proxy;
import java.io.Serializable;
import java.math.BigDecimal;

View File

@ -4,7 +4,7 @@
* 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.proxy;
package org.hibernate.orm.test.proxy;
/**

View File

@ -4,7 +4,7 @@
* 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.proxy;
package org.hibernate.orm.test.proxy;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;

View File

@ -4,7 +4,7 @@
* 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.proxy;
package org.hibernate.orm.test.proxy;
import java.io.Serializable;
/**

View File

@ -4,7 +4,7 @@
* 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.proxy;
package org.hibernate.orm.test.proxy;
import java.math.BigDecimal;
import java.util.List;
@ -42,6 +42,11 @@ public class ProxyTest extends BaseCoreFunctionalTestCase {
return new String[] { "proxy/DataPoint.hbm.xml" };
}
@Override
protected String getBaseForMappings() {
return "org/hibernate/orm/test/";
}
@Override
public void configure(Configuration cfg) {
super.configure( cfg );

View File

@ -31,6 +31,7 @@ public class ProxyInterceptor extends EmptyInterceptor {
* @param object The presumed entity instance.
* @return The entity name (pointing to the proper entity mapping).
*/
@Override
public String getEntityName(Object object) {
String entityName = ProxyHelper.extractEntityName( object );
if ( entityName == null ) {

View File

@ -19,6 +19,7 @@ public class EntityNameInterceptor extends EmptyInterceptor {
* @param object The presumed entity instance.
* @return The entity name (pointing to the proper entity mapping).
*/
@Override
public String getEntityName(Object object) {
String entityName = ProxyHelper.extractEntityName( object );
if ( entityName == null ) {

View File

@ -1,99 +0,0 @@
/*
* 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.interfaceproxy;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
/**
* @author Gavin King
*/
public class InterfaceProxyTest extends BaseCoreFunctionalTestCase {
@Override
public String[] getMappings() {
return new String[] { "interfaceproxy/Item.hbm.xml" };
}
@Test
@RequiresDialectFeature(
value = DialectChecks.SupportsExpectedLobUsagePattern.class,
comment = "database/driver does not support expected LOB usage pattern"
)
public void testInterfaceProxies() {
Session s = openSession( new DocumentInterceptor() );
Transaction t = s.beginTransaction();
Document d = new DocumentImpl();
d.setName("Hibernate in Action");
d.setContent( s.getLobHelper().createBlob( "blah blah blah".getBytes() ) );
Long did = (Long) s.save(d);
SecureDocument d2 = new SecureDocumentImpl();
d2.setName("Secret");
d2.setContent( s.getLobHelper().createBlob( "wxyz wxyz".getBytes() ) );
// SybaseASE15Dialect only allows 7-bits in a byte to be inserted into a tinyint
// column (0 <= val < 128)
d2.setPermissionBits( (byte) 127 );
d2.setOwner("gavin");
Long d2id = (Long) s.save(d2);
t.commit();
s.close();
s = openSession( new DocumentInterceptor() );
t = s.beginTransaction();
d = (Document) s.load(ItemImpl.class, did);
assertEquals( did, d.getId() );
assertEquals( "Hibernate in Action", d.getName() );
assertNotNull( d.getContent() );
d2 = (SecureDocument) s.load(ItemImpl.class, d2id);
assertEquals( d2id, d2.getId() );
assertEquals( "Secret", d2.getName() );
assertNotNull( d2.getContent() );
s.clear();
d = (Document) s.load(DocumentImpl.class, did);
assertEquals( did, d.getId() );
assertEquals( "Hibernate in Action", d.getName() );
assertNotNull( d.getContent() );
d2 = (SecureDocument) s.load(SecureDocumentImpl.class, d2id);
assertEquals( d2id, d2.getId() );
assertEquals( "Secret", d2.getName() );
assertNotNull( d2.getContent() );
assertEquals( "gavin", d2.getOwner() );
//s.clear();
d2 = (SecureDocument) s.load(SecureDocumentImpl.class, did);
assertEquals( did, d2.getId() );
assertEquals( "Hibernate in Action", d2.getName() );
assertNotNull( d2.getContent() );
try {
d2.getOwner(); //CCE
assertFalse(true);
}
catch (ClassCastException cce) {
//correct
}
s.createQuery( "delete ItemImpl" ).executeUpdate();
t.commit();
s.close();
}
}

View File

@ -46,7 +46,7 @@ public class DocumentInterceptor implements Interceptor {
}
public boolean onSave(
Object entity, Serializable id, Object[] state,
Object entity, Object id, Object[] state,
String[] propertyNames, Type[] types
) throws CallbackException {
if ( entity instanceof Document ) {

View File

@ -180,6 +180,20 @@ where `param` is bound to `entityManager.getReference(EntityClass.class, 1)`.
** 'hibernate.classLoader.application', 'hibernate.classLoader.resources', 'hibernate.classLoader.hibernate' and 'hibernate.classLoader.environment': use 'hibernate.classLoaders' instead.
** 'hibernate.hbm2dll.create_namespaces': use 'jakarta.persistence.create-database-schemas' or 'hibernate.hbm2ddl.create_namespaces'
=== org.hibernate.Interceptors
The method
```
boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types)
```
has been removed in favour of
```
boolean onSave(Object entity, Object id, Object[] state, String[] propertyNames, Type[] types)
```
=== Fetch behaviour change
We changed the way we detect circularity, we do not follow anymore a deep first detection, so what happens is that in a model like