read-only cmp bean
eprst Sep 23, 2008 2:41 AMHi
I'm trying to figure out how to implement read-only CMP 2.0 bean in JBoss 4.x
My current attempt to define it like this doesn't work:
/**
 * ...
 * @jboss.read-only "true"
 */
public abstract class MyBean implements EntityBean {
//....
 /**
 * @ejb.pk-field
 * @ejb.persistence
 * @ejb.interface-method view-type="local"
 * @jboss.column-name "foo"
 */
 public abstract Long getFoo();
 public abstract void setFoo(Long newValue);
//...
 /**
 * @ejb:create-method
 * @ejb:transaction type="Required"
 */
 public MyPK ejbCreate(Long foo)
 throws CreateException {
 setFoo(foo); //throws exception
 return null;
 }
//...
}
This essentially results in this code in jbosscmp-jdbc.xml:
<entity> <ejb-name>My</ejb-name> <read-only>true</read-only> <table-name>xxx</table-name> <cmp-field> <field-name>foo</field-name> <column-name>foo</column-name> </cmp-field> etc
However, an attempt to create such beans leads to exception in JBoss 4.x:
Caused by: javax.ejb.EJBException: Field is read-only: fieldName=foo at org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCAbstractCMPFieldBridge.setValue(JDBCAbstractCMPFieldBridge.java:232) at org.jboss.ejb.plugins.cmp.bridge.EntityBridgeInvocationHandler$FieldSetInvoker.invoke(EntityBridgeInvocationHandler.java:170) at org.jboss.ejb.plugins.cmp.bridge.EntityBridgeInvocationHandler.invoke(EntityBridgeInvocationHandler.java:105) at org.jboss.proxy.compiler.Runtime.invoke(Runtime.java:76) at xxx.MyCMP$Proxy.setFoo(<generated>) at xxx.MyBean.ejbCreate(MyBean.java:114)
How am I supposed to create instances without calling set* methods from ejbCreate?
May be I'm wrong, but this piece in JDBCAbstractCMPFieldBridge.java looks suspicious:
 public void setValue(EntityEnterpriseContext ctx, Object value)
 {
 if(isReadOnly())
 {
 throw new EJBException("Field is read-only: fieldName=" + fieldName);
 }
 if(primaryKeyMember && JDBCEntityBridge.isEjbCreateDone(ctx))
 {
 throw new IllegalStateException("A CMP field that is a member " +
 "of the primary key can only be set in ejbCreate " +
 "[EJB 2.0 Spec. 10.3.5].");
 }
I'd expect it to be something along "if(isReadOnly() && !JDBCEntityBridge.isEjbCreateDone(ctx))". This souldn't mark an instance as dirty one of course.
