Bug 172072 - "Entity Classes from Database" generates inappropriate methods
"Entity Classes from Database" generates inappropriate methods
Status: NEW
Product: db
Classification: Unclassified
Component: DB schema
6.x
All All
: P3 (vote)
: 7.0.1
Assigned To: Libor Fischmeistr
issues@db
javaee-blitz
:
: 177448 (view as bug list)
Depends on:
Blocks: 177448
  Show dependency treegraph
 
Reported: 2009-09-12 00:32 UTC by err
Modified: 2013-08-01 12:52 UTC (History)
2 users (show)

See Also:
Issue Type: DEFECT
:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description err 2009-09-12 00:32:10 UTC
In a class made by "entity class from database" there is

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "ID", nullable = false)
    private Integer id;

The following methods are also generated. But seems they are invalid for an auto generated field. It would be an error
for an application to use them.

    public Person(Integer id) {
        this.id = id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
Comment 1 Sergey Petrov 2009-09-12 06:24:53 UTC
Is there any realm error if I'll use these methods?
Comment 2 err 2009-09-12 13:41:51 UTC
        em.getTransaction().begin();
        p1.setId(1000000);
        em.getTransaction().commit();
results in

Exception [EclipseLink-7251] (Eclipse Persistence Services - 2.0.0.v20090821-r4934):
org.eclipse.persistence.exceptions.ValidationException
Exception Description: The attribute [id] of class [org.metawb.astro.db.Person] is mapped to a primary key column in the
database. Updates are not allowed.
javax.persistence.RollbackException: Exception [EclipseLink-7251] (Eclipse Persistence Services -
2.0.0.v20090821-r4934): org.eclipse.persistence.exceptions.ValidationException
Exception Description: The attribute [id] of class [org.metawb.astro.db.Person] is mapped to a primary key column in the
database. Updates are not allowed.
        at
org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:102)
        at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:63)
        at org.metawb.astro.db.PersonTest.setUp(PersonTest.java:61)
Caused by: Exception [EclipseLink-7251] (Eclipse Persistence Services - 2.0.0.v20090821-r4934):
org.eclipse.persistence.exceptions.ValidationException
Exception Description: The attribute [id] of class [org.metawb.astro.db.Person] is mapped to a primary key column in the
database. Updates are not allowed.
        at org.eclipse.persistence.exceptions.ValidationException.primaryKeyUpdateDisallowed(ValidationException.java:2372)
        ......


and


        clearDb();

        assert em == null;
        getEm();
        em.getTransaction().begin();
        p1 = new Person(1000000);
        em.persist(p1);
        em.getTransaction().commit();

        em.getTransaction().begin();
        p1.setFirstName("Ernie");
        em.getTransaction().commit();
        relEm();

gives surprising results, notice that the "p1.setFirstName("Ernie");" is lost somewhere. In some ways it seems an
exception should be thrown.

ij> select * from person;
ID         |LAST_NAME  |FIRST_NAME |MIDDLE_NAME
-----------------------------------------------
21         |NULL       |NULL       |NULL

1 row selected


Finally, using the correct constructor
        p1 = new Person();
in the previous example gives the expected results

ij> select * from person;
ID         |LAST_NAME  |FIRST_NAME  |MIDDLE_NAME
------------------------------------------------
22         |NULL       |Ernie       |NULL

1 row selected

I would guess that there are cases where they could be used with em.merge if you knew the id. But these seem rare and
specialized cases that shouldn't be in the default classes (my opinion).
Comment 3 Sergey Petrov 2009-09-14 10:05:31 UTC
"Exception [EclipseLink-7251] (Eclipse Persistence Services - 2.0.0.v20090821-r4934):
org.eclipse.persistence.exceptions.ValidationException
Exception Description: The attribute [id] of class [org.metawb.astro.db.Person] is mapped to a primary key column in the
database. Updates are not allowed."
it's look like an issue with attempt to update primary key and not the issue with autogenerated key. 
As for second sample with missed name it may be eclipselink/database issue or need additional investigation. Is there
any real restrictions from database side to specify id for new row instead of autogenerate?
Comment 4 err 2009-09-14 16:04:27 UTC
I understand why it is behaving this way, I believe the run-time behavior is correct.

The idea of this issue: the created methods and constructors that allow the programmer to attempt to set the "ID" are
invalid. They should not be auto created by the "entity from database" action because if they are used then errors or
unexpected things happen.

For this table in derby, the sql create is

    CREATE  TABLE ernie.person (
      id INT NOT NULL GENERATED ALWAYS AS IDENTITY ,
      last_name VARCHAR(45) ,
      first_name VARCHAR(45) ,
      middle_name VARCHAR(45) ,
      PRIMARY KEY (id) )
    ;

I am assuming there is enough info in the db schema to know that the column can not be written, that is is only autogen
(but I don't know for sure).
Comment 5 Sergey Petrov 2009-09-14 17:20:52 UTC
"if they are used then errors or
unexpected things happen." it may be only in case of inappropriate usage, otehrwise we can say no methods should be
generated for fields with "not null" constraint, as user can try to call setId(null) and persist (and it will cause
error) in case if it's not autogenerated field etc.
Comment 6 Sergey Petrov 2009-09-14 17:27:54 UTC
may be I need to try some use-cases first (with usage of constructor and setter in case of autogenerated pk)
Comment 7 Sergey Petrov 2009-09-14 17:39:51 UTC
for example I can create
create table greetings
	(i int generated by default as identity, ch char(50));
and PK will be autogenerated and derby will allow to specify pk anyway.
Comment 8 err 2009-09-14 18:06:37 UTC
>          generated by default as identity
> derby will allow specify pk

Yes, that is true. But in my example, I have

>          GENERATED ALWAYS AS IDENTITY
and you can *not* specify pk

If there is a standard way to determine that difference from the schema (or however the action works) then it seems the
second case should not have the methods/constructors that allow the pk to be set.

I don't think this is a serious problem, it is just that the class has confusing and misleading methods.

Consider

    CREATE  TABLE ernie.eventType (
      id INT NOT NULL GENERATED ALWAYS AS IDENTITY ,
      name VARCHAR(45) NOT NULL ,
      PRIMARY KEY (id) )

The only generated constructor to set the name is

    public Eventtype(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

but this is misleading, what I really want

    public Eventtype(String name) {
        this.name = name;
    }
Comment 9 Sergey Petrov 2009-09-21 11:45:52 UTC
yes, looks reasonable to generate Eventtype(String name), but also should be not problem with call 'new Eventtype(null,
name)'. as it's not serious problem and mostly usability issue, it may more like enhancement request for better support
for 'GENERATED ALWAYS AS IDENTITY' keys.
Comment 10 Sergey Petrov 2009-09-29 16:18:22 UTC
I don't see appropriate api in org.netbeans.modules.dbschema.ColumnElement, pass for evaluation.
feel free to pass back and file separate issue if it will be more appropriate.
Comment 11 Sergey Petrov 2009-09-29 16:22:57 UTC
I mean api to get if it's ALWAYS or DEFAULT auto-increment.
Comment 12 Sergey Petrov 2011-10-11 15:29:11 UTC
*** Bug 177448 has been marked as a duplicate of this bug. ***


By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2012, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo