HHH-5465 - HQL left join fetch of an element collection following a left join fetch of a one-to-one relationship causes NullPointerException (testcase)

This commit is contained in:
Christian Beikov 2013-05-01 22:50:34 +02:00 committed by Brett Meyer
parent 0fc57f6cc5
commit 33268fe0dd
4 changed files with 302 additions and 0 deletions

View File

@ -0,0 +1,97 @@
package org.hibernate.test.collection.set.hhh8206;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Basic;
import javax.persistence.CollectionTable;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name="contact")
public class Contact implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String name;
private Set<EmailAddress> emailAddresses = new HashSet<EmailAddress>();
private Set<EmailAddress> emailAddresses2 = new HashSet<EmailAddress>();
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Basic
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@ElementCollection
@CollectionTable(name = "user_email_addresses2", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"))
public Set<EmailAddress> getEmailAddresses2() {
return emailAddresses2;
}
public void setEmailAddresses2(Set<EmailAddress> emailAddresses2) {
this.emailAddresses2 = emailAddresses2;
}
@ElementCollection
@CollectionTable(name = "user_email_addresses", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"))
public Set<EmailAddress> getEmailAddresses() {
return emailAddresses;
}
public void setEmailAddresses(Set<EmailAddress> emailAddresses) {
this.emailAddresses = emailAddresses;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof Contact)) {
return false;
}
final Contact other = (Contact) obj;
if (this.id == null || other.id == null) {
return this == obj;
}
if(!this.id.equals(other.id)) {
return this == obj;
}
return true;
}
@Override
public String toString() {
return "com.clevercure.web.hibernateissuecache.User[ id=" + id + " ]";
}
}

View File

@ -0,0 +1,57 @@
package org.hibernate.test.collection.set.hhh8206;
import java.io.Serializable;
import java.util.Set;
import javax.persistence.*;
@Embeddable
public class EmailAddress implements Serializable {
private static final long serialVersionUID = 1L;
private String email;
public EmailAddress() {
}
public EmailAddress(String email) {
this.email = email;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public int hashCode() {
int hash = 0;
hash += (email != null ? email.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof EmailAddress)) {
return false;
}
final EmailAddress other = (EmailAddress) obj;
if (this.email == null || other.email == null) {
return this == obj;
}
if(!this.email.equals(other.email)) {
return this == obj;
}
return true;
}
@Override
public String toString() {
return "com.clevercure.web.hibernateissuecache.EmailAddress[ email=" + email + " ]";
}
}

View File

@ -0,0 +1,61 @@
package org.hibernate.test.collection.set.hhh8206;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Assert;
import org.junit.Test;
public class JoinFetchElementCollectionTest extends BaseCoreFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] {Contact.class, EmailAddress.class, User.class};
}
@Test
public void test(){
Set<EmailAddress> emailAddresses = new HashSet<EmailAddress>();
emailAddresses.add(new EmailAddress("test1@test.com"));
emailAddresses.add(new EmailAddress("test2@test.com"));
emailAddresses.add(new EmailAddress("test3@test.com"));
{
// Session 1: Insert a user with email addresses but no emailAddresses2
Session session = openSession();
session.beginTransaction();
User user = new User();
user.setName("john");
Contact contact = new Contact();
contact.setName("John Doe");
contact.setEmailAddresses(emailAddresses);
contact = (Contact) session.merge(contact);
user.setContact(contact);
user = (User) session.merge(user);
session.getTransaction().commit();
session.close();
}
{
// Session 2: Retrieve the user object and check if the sets have the expected values
Session session = openSession();
session.beginTransaction();
User user = (User) session.createQuery("SELECT user "
+ "FROM User user "
+ "LEFT OUTER JOIN FETCH user.contact "
+ "LEFT OUTER JOIN FETCH user.contact.emailAddresses2 "
+ "LEFT OUTER JOIN FETCH user.contact.emailAddresses")
.uniqueResult();
session.getTransaction().commit();
session.close();
Assert.assertEquals(emailAddresses, user.getContact().getEmailAddresses());
Assert.assertTrue(user.getContact().getEmailAddresses2().isEmpty());
}
}
}

View File

@ -0,0 +1,87 @@
package org.hibernate.test.collection.set.hhh8206;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Basic;
import javax.persistence.CollectionTable;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name="users")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String name;
private Contact contact;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Basic
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@ManyToOne(optional = true)
@JoinColumn(name = "contact_id", nullable = true, unique = true)
public Contact getContact() {
return contact;
}
public void setContact(Contact contact) {
this.contact = contact;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof User)) {
return false;
}
final User other = (User) obj;
if (this.id == null || other.id == null) {
return this == obj;
}
if(!this.id.equals(other.id)) {
return this == obj;
}
return true;
}
@Override
public String toString() {
return "com.clevercure.web.hibernateissuecache.User[ id=" + id + " ]";
}
}