Author: hardy.ferentschik
Date: 2008-06-24 15:03:32 -0400 (Tue, 24 Jun 2008)
New Revision: 14801
Added:
annotations/trunk/src/test/org/hibernate/test/annotations/immutable/Foobar.java
annotations/trunk/src/test/org/hibernate/test/annotations/immutable/State.java
Removed:
annotations/trunk/src/test/org/hibernate/test/annotations/immutable/Country.hbm.xml
annotations/trunk/src/test/org/hibernate/test/annotations/immutable/CountryHbm.java
Modified:
annotations/trunk/doc/reference/en/modules/entity.xml
annotations/trunk/src/java/org/hibernate/annotations/Immutable.java
annotations/trunk/src/java/org/hibernate/cfg/annotations/PropertyBinder.java
annotations/trunk/src/test/org/hibernate/test/annotations/immutable/Country.java
annotations/trunk/src/test/org/hibernate/test/annotations/immutable/ImmutableTest.java
Log:
ANN-733
- Updated documentation
- Added some more tests and deleted obsolete test
- Modified PropertyBinder to throw AnnotationException in case @immutable is placed on a
simple property
Modified: annotations/trunk/doc/reference/en/modules/entity.xml
===================================================================
--- annotations/trunk/doc/reference/en/modules/entity.xml 2008-06-23 21:25:21 UTC (rev
14800)
+++ annotations/trunk/doc/reference/en/modules/entity.xml 2008-06-24 19:03:32 UTC (rev
14801)
@@ -2361,10 +2361,15 @@
</listitem>
</itemizedlist>
- <para><literal>@Immutable</literal> marks an entity as immutable.
The
- entity may not be updated or deleted by the application. This allows
- Hibernate to make some minor performance optimizations.
- <literal>@Immutable</literal> must be use on root entities
only.</para>
+ <para><literal>@Immutable</literal> marks an entity or collection
as immutable. An immutable
+ entity may not be updated by the application. This allows
+ Hibernate to make some minor performance optimizations. Updates to an immutable
+ entity will be ignored, but no exception is thrown.
+ <literal>@Immutable</literal> must be used on root entities only.
<literal>@Immutable</literal>
+ placed on a collection makes the collection immutable,
+ meaning additions and deletions to and from the collection are not allowed. A
+ <literal>HibernateException</literal> is thrown in this case.
+ </para>
<para><literal>@Persister</literal> lets you define your own
custom
persistence strategy. You may, for example, specify your own subclass of
Modified: annotations/trunk/src/java/org/hibernate/annotations/Immutable.java
===================================================================
--- annotations/trunk/src/java/org/hibernate/annotations/Immutable.java 2008-06-23
21:25:21 UTC (rev 14800)
+++ annotations/trunk/src/java/org/hibernate/annotations/Immutable.java 2008-06-24
19:03:32 UTC (rev 14801)
@@ -4,8 +4,15 @@
import java.lang.annotation.*;
/**
- * Mark an Entity or a Collection as immutable
- * No annotation means the element is mutable
+ * Mark an Entity or a Collection as immutable. No annotation means the element is
mutable.
+ * <p>
+ * An immutable entity may not be updated by the application. Updates to an immutable
+ * entity will be ignored, but no exception is thrown. @Immutable must be used
on root entities only.
+ * </p>
+ * <p>
+ * @Immutable placed on a collection makes the collection immutable, meaning
additions and
+ * deletions to and from the collection are not allowed. A
<i>HibernateException</i> is thrown in this case.
+ * </p>
*
* @author Emmanuel Bernard
*/
Modified: annotations/trunk/src/java/org/hibernate/cfg/annotations/PropertyBinder.java
===================================================================
---
annotations/trunk/src/java/org/hibernate/cfg/annotations/PropertyBinder.java 2008-06-23
21:25:21 UTC (rev 14800)
+++
annotations/trunk/src/java/org/hibernate/cfg/annotations/PropertyBinder.java 2008-06-24
19:03:32 UTC (rev 14801)
@@ -7,6 +7,7 @@
import org.hibernate.AnnotationException;
import org.hibernate.annotations.Generated;
import org.hibernate.annotations.GenerationTime;
+import org.hibernate.annotations.Immutable;
import org.hibernate.annotations.NaturalId;
import org.hibernate.annotations.OptimisticLock;
import org.hibernate.annotations.common.reflection.XClass;
@@ -73,7 +74,7 @@
public void setColumns(Ejb3Column[] columns) {
insertable = columns[0].isInsertable();
updatable = columns[0].isUpdatable();
- //concsistency is checked later when we know the proeprty name
+ //consistency is checked later when we know the property name
this.columns = columns;
}
@@ -94,7 +95,10 @@
}
private void validateBind() {
- //TODO check necessary params for a bind
+ if (property.isAnnotationPresent(Immutable.class)) {
+ throw new AnnotationException("@Immutable on property not allowed. " +
+ "Only allowed on entity level or on a collection.");
+ }
}
private void validateMake() {
Deleted:
annotations/trunk/src/test/org/hibernate/test/annotations/immutable/Country.hbm.xml
===================================================================
---
annotations/trunk/src/test/org/hibernate/test/annotations/immutable/Country.hbm.xml 2008-06-23
21:25:21 UTC (rev 14800)
+++
annotations/trunk/src/test/org/hibernate/test/annotations/immutable/Country.hbm.xml 2008-06-24
19:03:32 UTC (rev 14801)
@@ -1,12 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD
3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
-<!-- Generated Nov 9, 2006 6:27:53 PM by Hibernate Tools 3.2.0.beta7 -->
-<hibernate-mapping>
- <class name="org.hibernate.test.annotations.immutable.CountryHbm"
mutable="false">
- <id name="id" column="id"
type="java.lang.Integer">
- <generator class="native"/>
- </id>
- <property name="name"/>
- </class>
-</hibernate-mapping>
\ No newline at end of file
Modified:
annotations/trunk/src/test/org/hibernate/test/annotations/immutable/Country.java
===================================================================
---
annotations/trunk/src/test/org/hibernate/test/annotations/immutable/Country.java 2008-06-23
21:25:21 UTC (rev 14800)
+++
annotations/trunk/src/test/org/hibernate/test/annotations/immutable/Country.java 2008-06-24
19:03:32 UTC (rev 14801)
@@ -5,10 +5,15 @@
* @author Hardy Ferentschik
*/
import java.io.Serializable;
+import java.util.List;
+
import javax.persistence.Entity;
+import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.Immutable;
@Entity
@@ -16,7 +21,10 @@
@SuppressWarnings("serial")
public class Country implements Serializable {
private Integer id;
+
private String name;
+
+ private List<State> states;
@Id
@GeneratedValue
@@ -24,7 +32,6 @@
return id;
}
- @Immutable
public String getName() {
return name;
}
@@ -36,4 +43,15 @@
public void setName(String string) {
name = string;
}
+
+ @OneToMany(fetch = FetchType.LAZY)
+ @Cascade(org.hibernate.annotations.CascadeType.ALL)
+ @Immutable
+ public List<State> getStates() {
+ return states;
+ }
+
+ public void setStates(List<State> states) {
+ this.states = states;
+ }
}
Deleted:
annotations/trunk/src/test/org/hibernate/test/annotations/immutable/CountryHbm.java
===================================================================
---
annotations/trunk/src/test/org/hibernate/test/annotations/immutable/CountryHbm.java 2008-06-23
21:25:21 UTC (rev 14800)
+++
annotations/trunk/src/test/org/hibernate/test/annotations/immutable/CountryHbm.java 2008-06-24
19:03:32 UTC (rev 14801)
@@ -1,29 +0,0 @@
-//$Id$
-package org.hibernate.test.annotations.immutable;
-
-/**
- * @author Hardy Ferentschik
- */
-import java.io.Serializable;
-
-@SuppressWarnings("serial")
-public class CountryHbm implements Serializable {
- private Integer id;
- private String name;
-
- public Integer getId() {
- return id;
- }
-
- public String getName() {
- return name;
- }
-
- public void setId(Integer integer) {
- id = integer;
- }
-
- public void setName(String string) {
- name = string;
- }
-}
Added: annotations/trunk/src/test/org/hibernate/test/annotations/immutable/Foobar.java
===================================================================
--- annotations/trunk/src/test/org/hibernate/test/annotations/immutable/Foobar.java
(rev 0)
+++
annotations/trunk/src/test/org/hibernate/test/annotations/immutable/Foobar.java 2008-06-24
19:03:32 UTC (rev 14801)
@@ -0,0 +1,37 @@
+// $Id$
+package org.hibernate.test.annotations.immutable;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+import org.hibernate.annotations.Immutable;
+
+/**
+ * @author Hardy Ferentschik
+ */
+@Entity
+public class Foobar {
+ @Id
+ @GeneratedValue
+ private Integer id;
+
+ @Immutable
+ private String name;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
Property changes on:
annotations/trunk/src/test/org/hibernate/test/annotations/immutable/Foobar.java
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Modified:
annotations/trunk/src/test/org/hibernate/test/annotations/immutable/ImmutableTest.java
===================================================================
---
annotations/trunk/src/test/org/hibernate/test/annotations/immutable/ImmutableTest.java 2008-06-23
21:25:21 UTC (rev 14800)
+++
annotations/trunk/src/test/org/hibernate/test/annotations/immutable/ImmutableTest.java 2008-06-24
19:03:32 UTC (rev 14801)
@@ -1,9 +1,22 @@
//$Id$
package org.hibernate.test.annotations.immutable;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hibernate.AnnotationException;
+import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
+import org.hibernate.cfg.AnnotationConfiguration;
+import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.test.annotations.TestCase;
+import org.hibernate.test.annotations.fkcircularity.A;
+import org.hibernate.test.annotations.fkcircularity.B;
+import org.hibernate.test.annotations.fkcircularity.C;
+import org.hibernate.test.annotations.fkcircularity.D;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -30,56 +43,122 @@
tx.commit();
s.close();
- try {
- s = openSession();
- tx = s.beginTransaction();
- Country germany = (Country) s.get(Country.class, country.getId());
- assertNotNull(germany);
- germany.setName("France");
- s.save(germany);
- s.delete(germany);
- tx.commit();
- s.close();
-// fail();
- } catch (Exception e) {
- log.debug("success");
- }
+ // try changing the entity
+ s = openSession();
+ tx = s.beginTransaction();
+ Country germany = (Country) s.get(Country.class, country.getId());
+ assertNotNull(germany);
+ germany.setName("France");
+ assertEquals("Local name can be changed", "France",
germany.getName());
+ s.save(germany);
+ tx.commit();
+ s.close();
+
+ // retrieving the country again - it should be unmodified
+ s = openSession();
+ tx = s.beginTransaction();
+ germany = (Country) s.get(Country.class, country.getId());
+ assertNotNull(germany);
+ assertEquals("Name should not have changed", "Germany",
germany.getName());
+ s.close();
+
+// // try deletion
+// s = openSession();
+// tx = s.beginTransaction();
+// s.delete(germany);
+// tx.commit();
+// s.close();
+//
+// s = openSession();
+// tx = s.beginTransaction();
+// germany = (Country) s.get(Country.class, country.getId());
+// assertNotNull(germany);
+// assertEquals("Name should not have changed", "Germany",
germany.getName());
+// s.close();
}
- public void testImmutableEntityWithMappingFile() throws Exception {
+ public void testImmutableCollection() {
+ Country country = new Country();
+ country.setName("Germany");
+ List states = new ArrayList<State>();
+ State bayern = new State();
+ bayern.setName("Bayern");
+ State hessen = new State();
+ hessen.setName("Hessen");
+ State sachsen = new State();
+ sachsen.setName("Sachsen");
+ states.add(bayern);
+ states.add(hessen);
+ states.add(sachsen);
+ country.setStates(states);
+
Session s = openSession();
Transaction tx = s.beginTransaction();
- CountryHbm country = new CountryHbm();
- country.setName("Germany");
s.persist(country);
tx.commit();
s.close();
-
+
+ s = openSession();
+ tx = s.beginTransaction();
+ Country germany = (Country) s.get(Country.class, country.getId());
+ assertNotNull(germany);
+ assertEquals("Wrong number of states", 3, germany.getStates().size());
+
+ // try adding a state
+ State foobar = new State();
+ foobar.setName("foobar");
+ s.save(foobar);
+ germany.getStates().add(foobar);
try {
- s = openSession();
- tx = s.beginTransaction();
- CountryHbm germany = (CountryHbm) s.get(CountryHbm.class, country.getId());
- assertNotNull(germany);
- germany.setName("France");
- s.save(germany);
- s.delete(germany);
tx.commit();
- s.close();
-// fail();
- } catch (Exception e) {
+ fail();
+ } catch (HibernateException e) {
+ assertTrue(e.getMessage().contains("changed an immutable collection
instance"));
log.debug("success");
}
- }
-
+ s.close();
+
+ s = openSession();
+ tx = s.beginTransaction();
+ germany = (Country) s.get(Country.class, country.getId());
+ assertNotNull(germany);
+ assertEquals("Wrong number of states", 3, germany.getStates().size());
+
+ // try deleting a state
+ germany.getStates().remove(0);
+ try {
+ tx.commit();
+ fail();
+ } catch (HibernateException e) {
+ assertTrue(e.getMessage().contains("changed an immutable collection
instance"));
+ log.debug("success");
+ }
+ s.close();
+
+ s = openSession();
+ tx = s.beginTransaction();
+ germany = (Country) s.get(Country.class, country.getId());
+ assertNotNull(germany);
+ assertEquals("Wrong number of states", 3, germany.getStates().size());
+ tx.commit();
+ s.close();
+ }
+
+ public void testMiscplacedImmutableAnnotation() {
+ try {
+ AnnotationConfiguration config = new AnnotationConfiguration();
+ config.addAnnotatedClass(Foobar.class);
+ config.buildSessionFactory();
+ fail();
+ } catch (AnnotationException ae) {
+ log.debug("succes");
+ }
+ }
+
/**
* @see org.hibernate.test.annotations.TestCase#getMappings()
*/
protected Class[] getMappings() {
- return new Class[] { Country.class };
+ return new Class[] { Country.class, State.class};
}
-
- @Override
- protected String[] getXmlFiles() {
- return new
String[]{"org/hibernate/test/annotations/immutable/Country.hbm.xml"};
- }
}
Added: annotations/trunk/src/test/org/hibernate/test/annotations/immutable/State.java
===================================================================
--- annotations/trunk/src/test/org/hibernate/test/annotations/immutable/State.java
(rev 0)
+++
annotations/trunk/src/test/org/hibernate/test/annotations/immutable/State.java 2008-06-24
19:03:32 UTC (rev 14801)
@@ -0,0 +1,34 @@
+// $Id$
+package org.hibernate.test.annotations.immutable;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+/**
+ * @author Hardy Ferentschik
+ */
+@Entity
+public class State {
+ @Id
+ @GeneratedValue
+ private Integer id;
+
+ private String name;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
Property changes on:
annotations/trunk/src/test/org/hibernate/test/annotations/immutable/State.java
___________________________________________________________________
Name: svn:keywords
+ Id