-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 
Author Message
 Post subject: Help with Polymorphic relationship
PostPosted: Wed Apr 13, 2016 4:26 pm 
Newbie

Joined: Wed Apr 13, 2016 10:40 am
Posts: 5
Hello,
I'm trying to prototype creating a Polymorphic @Any relationship between some data.
The technologies I'm using:

1) JavaEE 7
2) Spring 4.2.2.RELEASE (Core, MVC, Data,Persistence, ORM...)
3) Hibernate 4.2.20.FINAL
4) JPA 2
5) MySql 5.6


I'm going to be brief with the class description information for the sake of brevity.

For my Entities I have the following:

@Entity
@DiscriminatorValue(value = "INDIVIDUAL")
public class Individual implements IAssignee {
@Id
@Column(name = "uuid", unique = true, nullable = false, length = 37)
private String uuid = "";
@Column(name = "firstName", unique = false, nullable = false, length = 64)
private String firstName = "";
@Column(name = "lastName", unique = false, nullable = false, length = 64)
private String lastName = "";
@Column(name = "name", unique = false, nullable = false, length = 128)
private String name = "";
...
}


@Entity
@DiscriminatorValue(value = "UGROUP")
public class UserGroup implements IAssignee {
@Id
@Column(name = "uuid", unique = true, nullable = false, length = 37)
private String uuid = "";
@Column(name = "name", unique = false, nullable = false, length = 128)
private String name = "";
...
}

public interface IAssignee {
String getUuid();
String getName();
}

@Entity
public class WorkProduct {
@Id
@Column(name = "id", unique = true, nullable = false)
private int id = 0;

@Column(name = "name", unique = true, nullable = false, length = 37)
private String name = "";

@Any(metaColumn = @Column(name = "assigneeType"))
@AnyMetaDef(idType = "string", metaType = "string", metaValues = {
@MetaValue(targetEntity = Individual.class, value = "INDIVIDUAL"),
@MetaValue(targetEntity = UserGroup.class, value = "UGROUP") })
@Cascade({ org.hibernate.annotations.CascadeType.ALL })
@JoinColumn(name = "assigneeUuid", referencedColumnName = "uuid")
private IAssignee assignee;

}

Here is the SQL table descriptions:

CREATE TABLE `individual` (
`uuid` varchar(37) NOT NULL,
`firstName` varchar(64) NOT NULL,
`lastName` varchar(64) NOT NULL,
`name` varchar(128) NOT NULL,
PRIMARY KEY (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE `usergroup` (
`uuid` varchar(37) NOT NULL,
`name` varchar(128) NOT NULL,
PRIMARY KEY (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `workproduct` (
`id` int(11) NOT NULL,
`name` varchar(37) NOT NULL,
`assigneeType` int(11) NOT NULL,
`assigneeUuid` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Example of data in Individual table:

uuid firstName lastName name
-------------------------------------------------
"123" "john" "smith" "jsmith"


Example of data in UserGroup table:
uuid name
------------------------
"456" "Analyst"

Example of data in WorkProduct table

ID Name AssigneeType AssigneeUUID
------------------------------------------------------
1 productA 1 "123"
2 productB 2 "456"


So here's the issues, the AssigneeType ID is an integer value from my assigneeType table

id value
--------------
1 "INDIVIDUAL"
2 "UGROUP"


My @Any relationship in WorkProduct

@Any(metaColumn = @Column(name = "assigneeType"))
@AnyMetaDef(idType = "string", metaType = "string", metaValues = {
@MetaValue(targetEntity = Individual.class, value = "INDIVIDUAL"),
@MetaValue(targetEntity = UserGroup.class, value = "UGROUP") })
@Cascade({ org.hibernate.annotations.CascadeType.ALL })
@JoinColumn(name = "assigneeUuid", referencedColumnName = "uuid")
private IAssignee assignee;

is not working because assigneeType column is an integer value.
Can someone help me fix my @Any relationship declaration?

thanks,
mbeddedsoft


Top
 Profile  
 
 Post subject: Re: Help with Polymorphic relationship
PostPosted: Thu Apr 14, 2016 4:56 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1630
Location: Romania
Check out the @Any section on the new User Guide.

The `workproduct` product should be like this:

Code:
CREATE TABLE `workproduct` (
`id` int(11) NOT NULL,
`name` varchar(37) NOT NULL,
`assigneeType` varchar(255) NOT NULL,
`assigneeUuid` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


The workproduct should contain:

Code:
ID Name AssigneeType AssigneeUUID
------------------------------------------------------
1 productA INDIVIDUAL "123"
2 productB UGROUP "456"


And the mapping will work.

If the SQL table cannot be modified, and the `assigneeType` must be an int, then you need to change the @Any mapping:

Code:
@Any(metaColumn = @Column(name = "assigneeType"))
@AnyMetaDef(
    idType = "string",
    metaType = "integer",
    metaValues = {
        @MetaValue(targetEntity = Individual.class, value = "1"),
        @MetaValue(targetEntity = UserGroup.class, value = "2")
    }
)
@Cascade({ org.hibernate.annotations.CascadeType.ALL })
@JoinColumn(name = "assigneeUuid", referencedColumnName = "uuid")


Top
 Profile  
 
 Post subject: Re: Help with Polymorphic relationship
PostPosted: Thu Apr 14, 2016 6:58 am 
Newbie

Joined: Wed Apr 13, 2016 10:40 am
Posts: 5
mihalcea_vlad,

I thank you for your reply.

I did read the Hibernate documentation and understand that Hibernate will use the Class name string by default or the string value defined by @DescriminatorValue for the 'metaColumn = @Column'. This makes it easy to perform select/insert/updates. I was able to make that work with no problem.

However, here at work, they typically used integer Type IDs defined in a Type Table (like what I described in the AssigneeType Table).

So then I guess I'm going to have to inform them that if we are to proceed using our new Hibernate/JPA solution, we will need to adapt and do it this way.

To be clear then, am I correct in understanding that it's not possible for the 'metaColumn = @Column' to refer to an Integer?
I'm only asking because they are going to ask me this question and from all the documentation and books I've read about @Any relationships and polymorphic relationships it doesn't seem to be possible.

Thank you again for your quick response. :)


Top
 Profile  
 
 Post subject: Re: Help with Polymorphic relationship
PostPosted: Thu Apr 14, 2016 7:06 am 
Hibernate Team
Hibernate Team

Joined: Thu Sep 11, 2014 2:50 am
Posts: 1630
Location: Romania
The metaType can also be an integer. According to the Javadoc:

Quote:
Names the discriminator Hibernate Type for this Any/ManyToAny mapping.


I think you need to use "integer". Did you try this mapping?

Code:
@Any(metaColumn = @Column(name = "assigneeType"))
@AnyMetaDef(
    idType = "string",
    metaType = "integer",
    metaValues = {
        @MetaValue(targetEntity = Individual.class, value = "1"),
        @MetaValue(targetEntity = UserGroup.class, value = "2")
    }
)
@Cascade({ org.hibernate.annotations.CascadeType.ALL })
@JoinColumn(name = "assigneeUuid", referencedColumnName = "uuid")


Top
 Profile  
 
 Post subject: Re: Help with Polymorphic relationship
PostPosted: Fri Apr 15, 2016 2:52 pm 
Newbie

Joined: Wed Apr 13, 2016 10:40 am
Posts: 5
mihalcea_vlad,
I may have tried that but possibly had some other issue.

So, I went ahead and just set ASSIGNEETYPE column contain the class name for 'Individual' and 'UserGroup'. That worked fine in my prototype.

When I went to implement the same logic in our ~/dev/trunk code I keep getting this error:

MappingException: "Foreign key (FK_ovvdfqhmrpylbs1cuqcbovdf2:WORKPRODUCT [ASSIGNEETYPE,ASSIGNEEUUID])) must have same number of columns as the referenced primary key (INDIVIDUAL [UUID])"

Do you have any Idea what this is referring to?

I made changes to ~/dev/trunk classes for Individual and UserGroup so that they implement my IAssignee interface.
I also updated both classes so that they both have Primarykey named 'UUID' and a 'NAME' as defined by my interface.

I'm confused at the MappingException message.

mbeddedsoft


Top
 Profile  
 
 Post subject: Re: Help with Polymorphic relationship
PostPosted: Fri Apr 15, 2016 3:42 pm 
Newbie

Joined: Wed Apr 13, 2016 10:40 am
Posts: 5
I figured out the problem.

I have a bi-directional relation in my Individual to WorkProduct.

// bi-directional many-to-one association to WorkProduct
@OneToMany(mappedBy = "assignee")
private Set<WorkProduct> assignedWorkdProducts = TreeSet<WorkProduct>();

I commented out this in my Individual class and everything worked fine.

I think I need to figure out how to use a composite key mapping here because WorkProduct.assignee is the IAssignee assginee property mapped by the @Any relationship and uses the AsssigneeType and AssigneeUuid columns.


mbeddedsoft


Top
 Profile  
 
 Post subject: Re: Help with Polymorphic relationship
PostPosted: Mon Apr 18, 2016 11:57 am 
Newbie

Joined: Wed Apr 13, 2016 10:40 am
Posts: 5
Sigh,
Ok now I need help querying by Assignee.uuid parameter.

Here is my query code:

final String str= "select p from WorkProduct p where p.assignee.uuid ='123'";
final Query query = session.createQuery(str);
final List<String> list = query.list();

session.createQuery(str) throws this QueryException:
could not resolve property: assignee.uuid of: org.baeldung.persistence.entities.WorkProduct [select p from com.test.entities.WorkProduct p where p.assignee.uuid ='123']

I have data in the WorkProduct table.
If I use this query string "select p from WorkProduct p" everything works and I can iterate through the list and determine IAssignee types and see their properties after casting them appropriately.
However, I need to be able to query Workproducts by Assignee.uuid and I'm stuck.

I even tried this query "select p from WorkProduct p where (TYPE(p.assignee) = Individual and p.assignee.uuid ='123')" and got the same exception on p.assignee.uuid property.

Any thoughts or suggestions?

thanks,
mbeddedsoft


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.