persistence@glassfish.java.net

Re: part of an embedded object is read-only...

From: Wonseok Kim <guruwons_at_gmail.com>
Date: Tue, 8 Aug 2006 16:31:30 +0900

When I see the code AggregateObjectMapping's readOnly flag is always set
false so isReadOnly() seems to be meaningless.
I think it needs to check each field of AggregateObjectMapping for
read-only. Following can be one solution.

public void initialize(AbstractSession session) throws DescriptorException {
...
            // Add field to mapping association
            for (Enumeration fields = mapping.getFields().elements();
fields.hasMoreElements();) {
// Object field = fields.nextElement();
                DatabaseField field = (DatabaseField)
fields.nextElement();//field
is always DatabaseField
                if (!mapping.isReadOnly() && !field.isReadOnly()) {//PATCH:
if AggregateObjectMapping check if each field is read-only
                    if (getMappingsByField().containsKey(field)) {
                        // We cannot determine if aggregate mapping for the
field are read-only, so ignore exception.
                        if (!mapping.isAggregateObjectMapping()) {
                            session.getIntegrityChecker().handleError(
DescriptorException.multipleWriteMappingsForField(field.toString(),
mapping));
                        }
...

But this causes another problem in initializePrimaryKey() for Embedded
object which has read-only primary key like Sahoo's sample.

@Entity
public class Table1 implements java.io.Serializable {

@EmbeddedId
protected Table1PK table1PK;

@JoinColumn(name = "ID", referencedColumnName = "ID")
@OneToOne
private Table2 table2;
...

@Embeddable
public class Table1PK implements java.io.Serializable {

@Column(name = "ID", nullable = false, insertable=false, updatable=false)
private int id;
...

In initializePrimaryKey() it find and set primaryKeyMappings from
mappingsByField map which contains non-read-only mappings. So if embedded
object has read-only primary key, its AggregateObjectMapping can not be
found and put into primaryKeyMappings.
Instead another mapping OneToOneMapping is found and put into
primaryKeyMappings incorrectly(so cause problem later).

Basically I wonder that TopLink can handle read-only primary key mapping
properly, because when I have following mapping in another sample:

  @Id
  @Column(name="ID", insertable = false, updatable = false)
  public int id;

it throws following exception:

Exception Description: There should be one non-read-only mapping defined for
the primary key field [TABLE1.ID].
Descriptor: RelationalDescriptor(Table1 --> [DatabaseTable(TABLE1)])

So IMHO to fix the issue we need to be clear about read-only primary key
first.

-Wonseok

On 8/7/06, Sanjeeb Kumar Sahoo <Sanjeeb.Sahoo_at_sun.com> wrote:
>
> (Resending as the earlier email which had a wrong subject.)
>
> Hi Tom, Gordon,
>
> I am looking into issue
> https://glassfish.dev.java.net/issues/show_bug.cgi?id=894 . Looking at
> the code I see that the metadata processing code is correctly processing
> the insertable and updatable values that are specified in the Embeddable
> class. An *AggregateObjectMapping* type of mapping is also created for
> the embedded field. The bug seem to be in ObjectBuilder.java which is
> reporting an incorrect exception. See code below from ObjectBuilder.java:
> public void initialize(AbstractSession session) throws
> DescriptorException {
> ...
> if (!mapping.isReadOnly()) {
> if (getMappingsByField().containsKey(field)) {
> // We cannot determine if aggregate mapping for
> the field are read-only, so ignore exception.
> if (!mapping.isAggregateObjectMapping()) {
>
> session.getIntegrityChecker().handleError(
> DescriptorException.multipleWriteMappingsForField(field.toString(),
> mapping));
> }
> }
> ...
>
> As you can see, from the above code, it is checking if the
> AggregateObjectMapping is readonly or not. Should it not instead check
> individual mapping objects that are part of the AggregateObjectMapping?
> What I don't understand is why is their a boolean type field called
> *isReadOnly* on an AggregateObjectMapping. What is the semantics of that
> boolean flag? /Does TopLink Essential not support a part of an embedded
> object to be read-only?/
>
> Thanks,
> Sahoo
>



-- 
Wonseok Kim
Senior Developer, TmaxSoft