This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 91712 - Provide API for generation of entities from DB
Summary: Provide API for generation of entities from DB
Status: RESOLVED FIXED
Alias: None
Product: javaee
Classification: Unclassified
Component: Persistence (show other bugs)
Version: 6.x
Hardware: All All
: P1 blocker (vote)
Assignee: Erno Mononen
URL:
Keywords: API
Depends on:
Blocks: 91757
  Show dependency tree
 
Reported: 2007-01-03 09:04 UTC by Jan Stola
Modified: 2007-04-24 10:07 UTC (History)
3 users (show)

See Also:
Issue Type: TASK
Exception Reporter:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jan Stola 2007-01-03 09:04:26 UTC
Allow to reuse generation of entity classes from DB - provide some API
for this purpose. Provide a way to customize the generation e.g. to specify
whether related entities should be generated, whether to generate named queries,
whether include property change support etc.
Comment 1 Andrei Badea 2007-01-03 15:06:47 UTC
As we have talked, this probably includes refactoring existing classes related
to the newly generated ones. E.g. we have a table A in a 1:N relationship with a
table B and we first generate only table A and then table B. When the B class is
generated a relationship field should be added to A.
Comment 2 Andrei Badea 2007-03-02 12:53:57 UTC
I must warn that we probably won't have time to implement the refactoring in I
talked about in desc2 for 6.0.
Comment 3 Erno Mononen 2007-03-07 15:14:20 UTC
I'd like to start working on this finally, but I'd still need some further 
clarifications:
1. I assume that you don't want our current (or any) UI for this?
2. Do you want to able to generate entities for several tables or just for one 
(optionally including related tables) at time?
3. Are the default entity names that we currently generate fine or do you want 
to be able to set them?
4. Do you want that a progress dialog is shown during generation?



Comment 4 Jan Stola 2007-03-08 10:29:03 UTC
> 1. I assume that you don't want our current (or any) UI for this?

Yes, exactly.

> 2. Do you want to able to generate entities for several tables
> or just for one (optionally including related tables) at time?

Our current use-cases are
* generation of entity class for one table
* generation of entity classes for two tables (linked by foreign key)

> 3. Are the default entity names that we currently generate
> fine or do you want to be able to set them?

It would be nice to be able to customize them, but it is not critical for us.

> 4. Do you want that a progress dialog is shown during generation?

According to the current implementation (in NB 5.5) the generation seems
to be a long task. So, some progress indication (at least indeterminate
progress bar) is necessary.

The generation of the entity class will be just one of several
steps performed on our side. So, it would be nice to be able
to integrate your progress indication with our one (used for
the other steps) for example via ProgressContributor.
Comment 5 Erno Mononen 2007-03-08 15:20:50 UTC
Thanks for the clarifications, I'll propose an API based on these requirements 
in the coming days.
Comment 6 Erno Mononen 2007-03-12 20:37:06 UTC
Could you please still elaborate on the following requirement:

> * generation of entity classes for two tables (linked by foreign key)

Does it mean that you'd provide all related tables for which entities should be 
generated, or that you'd prefer to supply a table and specify whether entities 
for its related tables should be also generated? If the latter, do you also 
want to specify for which of the related tables (in case there are more than 
one) entities should be generated?
Comment 7 Jan Stola 2007-03-13 11:05:15 UTC
* generation of entity classes for two tables (linked by foreign key)

In this use case, I will be able to provide two tables (master and detail). The 
detail table will have a foreign key into the master table. For example: 
CUSTOMERS as a master table and ORDERS as a detail table. So, I would like to 
generate entities for just these two tables (and would like to make sure that 
the relation between them is also correctly covered by the generated classes 
e.g. something like getOrdersCollection() will be in the Customer class).
Comment 8 Erno Mononen 2007-03-21 17:43:46 UTC
I've committed o.n.m.j2ee.persistence.api.EntitiesFromDBGenerator to the 
merged_model branch, please have a look at it and let me know whether the API 
it provides is what you need. It is not finished as of now, in particular it 
does not utilize the progress contributor API. One open question is still 
whether you will take care of adding the generated entities as managed classes 
to the appropriate persistence unit or whether this API should do it, meaning 
that you'd need to pass a persistence unit to it.
Comment 9 Jan Stola 2007-03-27 13:09:28 UTC
The current version of the generator is unusable, unfortunately. First of all, 
it resides in a package that is not marked as public. That would be a minor 
issue if the package would not clash with a package with the same name in 
another module (e.g. in persistenceapi) - note that the class is in persistence 
module by now.

The generate() method of EntitiesFromDBGenerator seems to generate the entity 
class(es), but it doesn't return correct values. Note that 
JavaPersistenceGenerator.createdObjects returns Collections.EMPTY_SET instead 
of the set of generated beans.

As for the API, I would prefer to have List as a return type - to be able to 
match the generated files to DB tables easily e.g. the i-th element of the 
returned list would correspond to i-th table passed to the method.

I don't like that the generate() method can throw DBException from dbschema 
module. It seems silly to me to be forced to add a dependency on dbschema 
module just because of this exception. Please, don't disclose this exception in 
the API - you can, for example, wrap it in another exception.

> One open question is still whether you will take care of adding
> the generated entities as managed classes to the appropriate persistence
> unit or whether this API should do it, meaning that you'd need to pass
> a persistence unit to it.

It seems as a natural thing to add the generated classes into some persistence 
unit. On the other hand I am fine with both approaches. If the generate() 
method will not add them into a given persistence unit then I will add them in 
a subsequent code.
Comment 10 Erno Mononen 2007-03-27 14:11:28 UTC
Thanks for the comments. I noticed the same issue, i.e. that the returned set 
is always empty. I have it fixed and will commit the fix shortly to the 
merged_model branch. 

As for the rest of the concerns:

- package name: I'll change it to j2ee.persistence.api.entity.generator
- DBSchemaException: Agreed, I will remove it from the method signature
- persistence unit: I will add it as an optional parameter (optional since it 
can't be required for all project types)
- Set vs. List as the return type: This would require several changes in the 
current generating infrastructure. Do you have an actual use case for that or 
is it something that would be just nice to have?
Comment 11 Jan Stola 2007-03-28 17:01:15 UTC
> package name: I'll change it to j2ee.persistence.api.entity.generator

Thanks. There was an incorrect public package
org.netbeans.modules.j2ee.persistence.api.entity.generation
in j2ee/persistence/nbproject/project.xml. I have changed it 
to ...api.entity.generator

> DBSchemaException: Agreed, I will remove it from the method signature
> persistence unit: I will add it as an optional parameter (optional since
> it can't be required for all project types)

Great, but I have noticed that the current implementation adds
an incorrect class name into the persistence unit. For example for MASTER
table it generates Master class into package myPackage, but adds
<class>Master</class>
<class>myPackage.Master</class>
into persistence.xml. The second entry is correct, but the first one is invalid 
and should not be there. The first entry is added by 
JavaPersistenceGenerator$Generator:run:267. The second (correct) entry is added 
by EntitiesFromDBGenerator.addToPersistenceUnit:162.

> Set vs. List as the return type: This would require several changes in
> the current generating infrastructure. Do you have an actual use case
> for that or is it something that would be just nice to have?

It would be nice to have List instead of Set as a return type, but it is not 
critical. I can survive with a Set ;-).

The generator sometimes throws the following exception:
java.lang.NullPointerException
  at o.n.m.dbschema.jdbcimpl.TableElementImpl.initFKs(TableElementImpl.java:463)
  at o.n.m.dbschema.jdbcimpl.TableElementImpl.initKey(TableElementImpl.java:395)
  at o.n.m.dbschema.jdbcimpl.SchemaElementImpl.initTables
     (SchemaElementImpl.java:419)
  at o.n.m.dbschema.jdbcimpl.SchemaElementImpl.initTables
     (SchemaElementImpl.java:289)
  at o.n.m.j2ee.persistence.api.entity.generator.EntitiesFromDBGenerator
     .getSchemaElement(EntitiesFromDBGenerator.java:194)
  at o.n.m.j2ee.persistence.api.entity.generator.EntitiesFromDBGenerator
     .getTableClosure(EntitiesFromDBGenerator.java:168)
  at o.n.m.j2ee.persistence.api.entity.generator.EntitiesFromDBGenerator
     .generate(EntitiesFromDBGenerator.java:126)
  ...

It happens when I try to generate an entity class for a table with a foreign 
key into another table.
Comment 12 Erno Mononen 2007-03-28 20:52:52 UTC
> There was an incorrect public package
> org.netbeans.modules.j2ee.persistence.api.entity.generation
> in j2ee/persistence/nbproject/project.xml. I have changed it 
> to ...api.entity.generator

Oops - thanks for changing it.

> Great, but I have noticed that the current implementation adds
> an incorrect class name into the persistence unit. For example for MASTER
> table it generates Master class into package myPackage, but adds
> <class>Master</class>
> <class>myPackage.Master</class>
> into persistence.xml. The second entry is correct, but the first one is 
invalid 
> and should not be there. The first entry is added by 
> JavaPersistenceGenerator$Generator:run:267. The second (correct) entry is 
added 
> by EntitiesFromDBGenerator.addToPersistenceUnit:162.

Right, I'll fix it. I forgot about the automatic adding in the 
JavaPersistenceGenerator.  

> It would be nice to have List instead of Set as a return type, but it is not 
> critical. I can survive with a Set ;-).

OK, so if it is fine I'll leave it as a Set for now.

> The generator sometimes throws the following exception:
> java.lang.NullPointerException
>   at 
o.n.m.dbschema.jdbcimpl.TableElementImpl.initFKs(TableElementImpl.java:463)
>   at 
>   ...
>
> It happens when I try to generate an entity class for a table with a foreign 
> key into another table.

I'll have a look at this as well. As a general note, I'm still working on tests 
for this functionality, so hopefully things will gradually stabilize.
Comment 13 Erno Mononen 2007-04-23 13:30:28 UTC
An update on this: the remaining issues I'm aware of, i.e. the NPE and entities 
not being added to the specified PU, should be fixed now. Are there still other 
blockers or can we close this?
Comment 14 Jan Stola 2007-04-24 09:08:10 UTC
Feel free to close this issue as fixed/implemented.
Comment 15 Erno Mononen 2007-04-24 10:07:26 UTC
OK, closing.