HHH-13236 Honour @Column/insertable on element collections

This commit is contained in:
Dmitry Panov 2019-01-29 16:21:12 +00:00 committed by gbadner
parent f94bc0d750
commit aa2451407e
2 changed files with 119 additions and 3 deletions

View File

@ -160,6 +160,7 @@ public abstract class AbstractCollectionPersister
protected final String[] elementColumnReaderTemplates;
protected final String[] elementFormulaTemplates;
protected final String[] elementFormulas;
protected final boolean[] elementColumnIsGettable;
protected final boolean[] elementColumnIsSettable;
protected final boolean[] elementColumnIsInPrimaryKey;
protected final String[] indexColumnAliases;
@ -332,9 +333,15 @@ public abstract class AbstractCollectionPersister
elementFormulaTemplates = new String[elementSpan];
elementFormulas = new String[elementSpan];
elementColumnIsSettable = new boolean[elementSpan];
elementColumnIsGettable = new boolean[elementSpan];
elementColumnIsInPrimaryKey = new boolean[elementSpan];
boolean isPureFormula = true;
boolean hasNotNullableColumns = false;
boolean oneToMany = collectionBinding.isOneToMany();
boolean[] columnInsertability = null;
if (!oneToMany) {
columnInsertability = collectionBinding.getElement().getColumnInsertability();
}
int j = 0;
iter = collectionBinding.getElement().getColumnIterator();
while ( iter.hasNext() ) {
@ -351,7 +358,8 @@ public abstract class AbstractCollectionPersister
elementColumnWriters[j] = col.getWriteExpr();
elementColumnReaders[j] = col.getReadExpr( dialect );
elementColumnReaderTemplates[j] = col.getTemplate( dialect, factory.getSqlFunctionRegistry() );
elementColumnIsSettable[j] = true;
elementColumnIsGettable[j] = true;
elementColumnIsSettable[j] = oneToMany || columnInsertability[j];
elementColumnIsInPrimaryKey[j] = !col.isNullable();
if ( !col.isNullable() ) {
hasNotNullableColumns = true;
@ -1087,8 +1095,8 @@ public abstract class AbstractCollectionPersister
}
protected void appendElementColumns(SelectFragment frag, String elemAlias) {
for ( int i = 0; i < elementColumnIsSettable.length; i++ ) {
if ( elementColumnIsSettable[i] ) {
for ( int i = 0; i < elementColumnIsGettable.length; i++ ) {
if ( elementColumnIsGettable[i] ) {
frag.addColumnTemplate( elemAlias, elementColumnReaderTemplates[i], elementColumnAliases[i] );
}
else {

View File

@ -0,0 +1,108 @@
package org.hibernate.test.collection.nonInsertable;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import javax.persistence.*;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.*;
@TestForIssue(jiraKey = "HHH-13236")
public class NonInsertableColumnTest extends BaseCoreFunctionalTestCase {
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] {
Parent.class,
Child.class
};
}
@Override
protected void configure(Configuration configuration) {
super.configure( configuration );
configuration.setProperty( AvailableSettings.SHOW_SQL, "true" );
}
@Test
public void test() {
Session session = null;
Transaction transaction = null;
try {
session = openSession();
transaction = session.beginTransaction();
Child child = new Child();
child.field = "Test";
child.nonInsertable = "nonInsertable";
child.nonUpdatable = "nonUpdatable";
Parent parent = new Parent();
parent.children = Arrays.asList(child);
session.persist(parent);
session.flush();
transaction.commit();
session.clear();
Parent loaded = session.get(Parent.class, parent.id);
assertEquals("nonUpdatable", loaded.children.get(0).nonUpdatable);
assertNull(loaded.children.get(0).nonInsertable);
assertEquals("Test", loaded.children.get(0).field);
assertEquals("Test", loaded.children.get(0).shadowField);
} catch (HibernateException e) {
if (transaction != null) {
transaction.rollback();
}
fail(e.getMessage());
} finally {
if (session != null) {
session.close();
}
}
}
@Entity(name="Parent")
public static class Parent {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long id;
@ElementCollection
public List<Child> children;
}
@Embeddable
public static class Child {
@Column(name="field")
public String field;
@Column(insertable = false)
public String nonInsertable;
@Column(updatable = false)
public String nonUpdatable;
@Column(name="field", insertable = false, updatable = false)
public String shadowField;
}
}