Announcement Announcement Module
No announcement yet.
reference field in composite PK class Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • reference field in composite PK class


    I want to use a composite primary key for an "Issue" object, and one of the composite PK fields should actually be a reference to the ID of an existing entity (Account).

    The script is executed without error by the roo shell, just the mapping does not seem to work (in the scaffolded form for the Issue the "Account" field is a text-input and not a selectbox to an existing account.

    Is this possible at all with roo 1.2 ?

    My script looks like this:

    entity jpa --class ~.Account
    field string --fieldName name --notNull
    field date --fieldName dateCreated --type java.util.Date
    field date --fieldName dateModified --type java.util.Date

    entity jpa --class ~.Issue --identifierType ~.IssuePK
    field string --fieldName title --notNull
    //Id's fields
    field reference --fieldName accoundId --type ~.Account --class ~.IssuePK
    field string --fieldName issueId --notNull --class ~.IssuePK
    field string --fieldName issueUpdate --notNull --class ~.IssuePK

    Another question would be: Is it generally possible to add a "field reference" to an entity which references another entity which has a composite PK?
    Last edited by yglodt; Feb 5th, 2012, 05:02 PM.

  • #2
    Let me tell you that it isn't a Roo problem, but a JPA one.

    If you don't have a legacy database, I strongly recommend you to use auto-generated meaningless Primary Keys, this is going to facilitate everything you do in your development (for instance, the JSP generation and its fields)

    You can establish a lot of relationships with JPA, but you need to use the annotations @JoinColumns and @JoinColumn to describe them. With a lot of care in order to avoid repeated columns (so you will have to configure the values for updatable, insertable attributes)

    It isn't worth it (unless you have no other option, due to a legacy database)


    • #3
      Hello and thanks for your explanations.

      Speaking generally, not Spring nor Spring Roo related: I want to give one example of 3 classes with their respective PKs:

      Composite PKs in case of Employee and Address.

      Company (companyId)
      Employee (companyId, employeeId)
      Address (companyId, employeeId, addressId)

      So you would recommend burning this composite PKs, but just just using e.g. an UUID as PK, and create the relation between the entities with a simple string-field holding the UUID ? (which is the PK of the linked object)

      Did I get your suggestion correctly ? :-)
      Last edited by yglodt; Feb 6th, 2012, 04:46 PM.


      • #4
        My suggestion is based on the book "Java persistence with Hibernate" from Manning. There are a lot of explanations regarding IDs.

        You can keep the columns/fields that identifies the entities in your business, plus add auto-generated keys maintained by the database for identifying (both the the object in the memory, or first cache, and the record in the database) as well as referencing entities in relationship.

        I mean, try something like:

        entity jpa --class ~.domain.Company
        field string --name companyId
        // See the code, you'll have and @Id in the _Roo_Entity and your desired business ID in the java class.
        entity jpa --class ~.domain.Employee
        field string --name employeeId
        field reference --class ~.domain.Company
        // See the code and the generated tables.
        Note: review the script, I've written it without looking the documentation.

        With this approach, you can provide logical values in a form, for instance.

        Alternatively, you can rename the identifier column in the entity jpa command (use identifier column) But you will need to "push in..." the id attribute from the aspect in order to provide logical values instead of auto-generated.

        In any case, composite keys will complicate your development, and maybe you don't need them. But it depends on your requirements.


        • #5
          Referring to the first script from yglodt:

          There is yet another problem with Roo when using --testAutomatically parameter with the above entity creation commands.
          RunAs - Maven test thenfails with several ConstraintViolationException(s) "NULL not allowed for column "ACCOUND_ID"; SQL statement:
          insert into issue (title, version, accound_id, issue_id, issue_update) values (?, ?, ?, ?, ?) [23502-164]"

          Digging down into generated AspectJ file "IssueDataOnDemand_Roo_DataOnDemand.aj" , class "IssueDataOnDemand.setEmbeddedIdClass" reveals Roo setting "Account accoundId = null" which consequently results in a constraint validation during several other test generated methods.

          A challenge question to senior members: should be reported as a Roo bug?


          • #6
            If you want to establish a relationship between Issues and Accounts and you want to include some extra information in the relationship, maybe you need an intermediate entity.

            In such entity, AccountIssued, you can create an ID that relates to the Account, and even to the Issue (that allows reverse access)

            A lot of manual job is required for doing so. It would be preferable to use generated ids.

            I've found a little weird to relate a PK object with an Entity, because the former is a value-type (an @Embeddable) so it doesn't have a database identity (it belongs to an entity)


            • #7
              Can you design this? only one Primary Key for every table.

              Company (id, name, ...)
              Employee (id, name, ...)
              Address (id, name, ...)

              1:m Company-Employee => 1 join column in Employee with
              m:1 Employee-Address => 1 join column in Employee with