HHH-8464 normalize quoting on join column

This commit is contained in:
Brett Meyer 2013-09-05 12:39:55 -04:00
parent a5705e011e
commit a450630f36
5 changed files with 140 additions and 16 deletions

View File

@ -510,14 +510,17 @@ public class Ejb3JoinColumn extends Ejb3Column {
@Override
protected void addColumnBinding(SimpleValue value) {
if ( StringHelper.isEmpty( mappedBy ) ) {
String unquotedLogColName = StringHelper.unquote( getLogicalColumnName() );
String unquotedRefColumn = StringHelper.unquote( getReferencedColumn() );
String logicalColumnName = getMappings().getNamingStrategy()
final ObjectNameNormalizer nameNormalizer = getMappings().getObjectNameNormalizer();
final String logicalColumnName = nameNormalizer.normalizeIdentifierQuoting( getLogicalColumnName() );
final String referencedColumn = nameNormalizer.normalizeIdentifierQuoting( getReferencedColumn() );
final String unquotedLogColName = StringHelper.unquote( logicalColumnName );
final String unquotedRefColumn = StringHelper.unquote( referencedColumn );
String logicalCollectionColumnName = getMappings().getNamingStrategy()
.logicalCollectionColumnName( unquotedLogColName, getPropertyName(), unquotedRefColumn );
if ( StringHelper.isQuoted( getLogicalColumnName() ) || StringHelper.isQuoted( getLogicalColumnName() ) ) {
logicalColumnName = StringHelper.quote( logicalColumnName );
if ( StringHelper.isQuoted( logicalColumnName ) || StringHelper.isQuoted( referencedColumn ) ) {
logicalCollectionColumnName = StringHelper.quote( logicalCollectionColumnName );
}
getMappings().addColumnBinding( logicalColumnName, getMappingColumn(), value.getTable() );
getMappings().addColumnBinding( logicalCollectionColumnName, getMappingColumn(), value.getTable() );
}
}

View File

@ -0,0 +1,53 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* JBoss, Home of Professional Open Source
* Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the @authors tag. All rights reserved.
* See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License, v. 2.1.
* This program is distributed in the hope that it will be useful, but WITHOUT A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License,
* v.2.1 along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package org.hibernate.test.annotations.quote;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
/**
* @author Brett Meyer
*/
@Entity
public class House {
@Id
@GeneratedValue
private Long id;
private String streetAddress;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getStreetAddress() {
return streetAddress;
}
public void setStreetAddress(String streetAddress) {
this.streetAddress = streetAddress;
}
}

View File

@ -88,7 +88,8 @@ public class QuoteGlobalTest extends BaseCoreFunctionalTestCase {
User.class,
Role.class,
Phone.class,
Person.class
Person.class,
House.class
};
}
}

View File

@ -23,18 +23,20 @@
*/
package org.hibernate.test.annotations.quote;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
/**
* @author Emmanuel Bernard
*/
public class QuoteTest extends BaseCoreFunctionalTestCase {
@Test
public void testQuoteManytoMany() {
Session s = openSession();
@ -53,13 +55,39 @@ public class QuoteTest extends BaseCoreFunctionalTestCase {
assertEquals( "User_Role", configuration().getCollectionMapping( role ).getCollectionTable().getName() );
s.close();
}
@Test
@TestForIssue(jiraKey = "HHH-8464")
public void testDoubleQuoteJoinColumn() {
Session s = openSession();
s.getTransaction().begin();
User user = new User();
House house = new House();
user.setHouse( house );
s.persist( house );
s.persist( user );
s.getTransaction().commit();
s.clear();
s = openSession();
s.getTransaction().begin();
user = (User) s.get( User.class, user.getId() );
assertNotNull( user );
assertNotNull( user.getHouse() );
// seems trivial, but if quoting normalization worked on the join column, these should all be the same
assertEquals( user.getHouse().getId(), user.getHouse1() );
assertEquals( user.getHouse().getId(), user.getHouse2() );
s.getTransaction().commit();
s.close();
}
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] {
User.class,
Role.class,
Phone.class
Phone.class,
House.class
};
}
}

View File

@ -1,13 +1,18 @@
//$Id$
package org.hibernate.test.annotations.quote;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
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.Table;
/**
@ -17,13 +22,23 @@ import javax.persistence.Table;
@Table(name = "`User`")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@ManyToMany
private Set<Role> roles = new HashSet<Role>();
@ManyToMany
private Set<Role> roles = new HashSet<Role>();
// These exist solely for HHH-8464 to ensure that the various forms of quoting are normalized internally
// (using backticks), including the join column. Without normalization, the mapping will throw a
// DuplicateMappingException.
@ManyToOne
@JoinColumn(name = "\"house\"")
private House house;
@Column(name = "\"house\"", insertable = false, updatable = false )
private Long house1;
@Column(name = "`house`", insertable = false, updatable = false )
private Long house2;
public long getId() {
return id;
@ -40,4 +55,28 @@ public class User implements Serializable {
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
public House getHouse() {
return house;
}
public void setHouse(House house) {
this.house = house;
}
public Long getHouse1() {
return house1;
}
public void setHouse1(Long house1) {
this.house1 = house1;
}
public Long getHouse2() {
return house2;
}
public void setHouse2(Long house2) {
this.house2 = house2;
}
}