HHH-8371 Consider explicit column name's "_" in alias creation

This commit is contained in:
Brett Meyer 2013-07-23 22:02:38 -04:00
parent 5d1ebeda01
commit 4d9e182fed
8 changed files with 353 additions and 4 deletions

View File

@ -52,7 +52,8 @@ public final class StringHelper {
public static int lastIndexOfLetter(String string) {
for ( int i=0; i<string.length(); i++ ) {
char character = string.charAt(i);
if ( !Character.isLetter(character) /*&& !('_'==character)*/ ) return i-1;
// Include "_". See HHH-8073
if ( !Character.isLetter(character) && !('_'==character) ) return i-1;
}
return string.length()-1;
}

View File

@ -111,7 +111,7 @@ public class Column implements Selectable, Serializable, Cloneable {
@Override
public String getAlias(Dialect dialect) {
final int lastLetter = StringHelper.lastIndexOfLetter( name );
String suffix = Integer.toString(uniqueInteger) + '_';
final String suffix = Integer.toString(uniqueInteger) + '_';
String alias = name;
if ( lastLetter == -1 ) {

View File

@ -20,10 +20,15 @@
*/
package org.hibernate.test.mapping;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.Iterator;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.mapping.Table;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
@ -40,10 +45,17 @@ import org.junit.Test;
*
* @author Brett Meyer
*/
@TestForIssue( jiraKey = "HHH-2448" )
public class AliasTest extends BaseCoreFunctionalTestCase {
/**
* Column aliases utilize {@link Table#getUniqueInteger()} for naming. The unique integer used to be statically
* generated by the Table class, meaning it was dependent on mapping order. HHH-2448 made the alias names
* deterministic by having Configuration determine the unique integers on its second pass over the Tables tree map.
* AliasTest and {@link MappingReorderedAliasTest} ensure that the unique integers are the same, regardless of
* mapping ordering.
*/
@Test
@TestForIssue( jiraKey = "HHH-2448" )
public void testAliasOrdering() {
Iterator<Table> tables = configuration().getTableMappings();
Table table1 = null;
@ -60,9 +72,48 @@ public class AliasTest extends BaseCoreFunctionalTestCase {
assertTrue( table1.getUniqueInteger() < table2.getUniqueInteger() );
}
@Test
@TestForIssue( jiraKey = "HHH-8371" )
public final void testUnderscoreInColumnName() throws Throwable {
final Session s = openSession();
s.getTransaction().begin();
UserEntity user = new UserEntity();
user.setName( "foo" );
s.persist(user);
final ConfEntity conf = new ConfEntity();
conf.setConfKey("counter");
conf.setConfValue("3");
final UserConfEntity uc = new UserConfEntity();
uc.setUser(user);
uc.setConf(conf);
conf.getUserConf().add(uc);
s.persist(conf);
s.getTransaction().commit();
s.clear();
s.getTransaction().begin();
user = (UserEntity) s.get(UserEntity.class, user.getId());
try {
s.flush();
}
catch ( HibernateException e ) {
// original issue from HHH-8371
fail( "The explicit column name's underscore(s) were not considered during alias creation." );
}
assertNotNull( user );
assertEquals( user.getName(), "foo" );
s.getTransaction().commit();
s.close();
}
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { Table1.class, Table2.class };
return new Class<?>[] { Table1.class, Table2.class, ConfEntity.class, UserConfEntity.class, UserEntity.class };
}
}

View File

@ -0,0 +1,54 @@
package org.hibernate.test.mapping;
import static javax.persistence.CascadeType.ALL;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name = "CONF")
@IdClass(ConfId.class)
public class ConfEntity implements Serializable{
private static final long serialVersionUID = -5089484717715507169L;
@Id
@Column(name = "confKey")
private String confKey;
@Id
@Column(name = "confValue")
private String confValue;
@OneToMany(mappedBy="conf", cascade = ALL, orphanRemoval = true, fetch = FetchType.LAZY)
private Set<UserConfEntity> userConf = new HashSet<UserConfEntity>();
public String getConfKey() {
return confKey;
}
public void setConfKey(String confKey) {
this.confKey = confKey;
}
public String getConfValue() {
return confValue;
}
public void setConfValue(String confValue) {
this.confValue = confValue;
}
public Set<UserConfEntity> getUserConf() {
return userConf;
}
}

View File

@ -0,0 +1,67 @@
package org.hibernate.test.mapping;
import java.io.Serializable;
public class ConfId implements Serializable{
private static final long serialVersionUID = -6722022851594514199L;
private String confKey;
private String confValue;
public ConfId(){
}
public ConfId(String confKey, String confValue) {
this.confKey = confKey;
this.confValue = confValue;
}
public String getConfKey() {
return confKey;
}
public void setConfKey(String confKey) {
this.confKey = confKey;
}
public String getConfValue() {
return confValue;
}
public void setConfValue(String confValue) {
this.confValue = confValue;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((confKey == null) ? 0 : confKey.hashCode());
result = prime * result + ((confValue == null) ? 0 : confValue.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ConfId other = (ConfId) obj;
if (confKey == null) {
if (other.confKey != null)
return false;
} else if (!confKey.equals(other.confKey))
return false;
else if (confValue == null) {
if (other.confValue != null)
return false;
} else if (!confValue.equals(other.confValue))
return false;
return true;
}
}

View File

@ -0,0 +1,48 @@
package org.hibernate.test.mapping;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name = "USER_CONFS")
@IdClass(UserConfId.class)
public class UserConfEntity implements Serializable{
private static final long serialVersionUID = 9153314908821604322L;
@Id
@ManyToOne
@JoinColumn(name="user_id")
private UserEntity user;
@Id
@ManyToOne
@JoinColumns({
@JoinColumn(name="cnf_key", referencedColumnName="confKey"),
@JoinColumn(name="cnf_value", referencedColumnName="confValue")})
private ConfEntity conf;
public ConfEntity getConf() {
return conf;
}
public void setConf(ConfEntity conf) {
this.conf = conf;
}
public UserEntity getUser() {
return user;
}
public void setUser(UserEntity user) {
this.user = user;
}
}

View File

@ -0,0 +1,70 @@
package org.hibernate.test.mapping;
import java.io.Serializable;
public class UserConfId implements Serializable{
private static final long serialVersionUID = -161134972658451944L;
private Long user;
private ConfId conf;
public UserConfId(){
}
public UserConfId(Long user, ConfId conf) {
this.user = user;
this.conf = conf;
}
public Long getUser() {
return user;
}
public void setUser(Long user) {
this.user = user;
}
public ConfId getConf() {
return conf;
}
public void setConf(ConfId conf) {
this.conf = conf;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((conf == null) ? 0 : conf.hashCode());
result = prime * result + ((user == null) ? 0 : user.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
UserConfId other = (UserConfId) obj;
if (conf == null) {
if (other.conf != null)
return false;
} else if (!conf.equals(other.conf))
return false;
if (user == null) {
if (other.user != null)
return false;
} else if (!user.equals(other.user))
return false;
return true;
}
}

View File

@ -0,0 +1,58 @@
package org.hibernate.test.mapping;
import static javax.persistence.CascadeType.ALL;
import static javax.persistence.FetchType.EAGER;
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.Id;
import javax.persistence.OneToMany;
import javax.persistence.OrderColumn;
import javax.persistence.Table;
@Entity
@Table(name = "USER")
public class UserEntity implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
@Column(name = "user_id")
private Long id;
@OrderColumn(name = "cnf_order")
@OneToMany(mappedBy="user", fetch = EAGER, cascade = ALL, orphanRemoval = true)
private Set<UserConfEntity> confs = new HashSet<UserConfEntity>();
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Set<UserConfEntity> getConfs() {
return confs;
}
public void setConfs(Set<UserConfEntity> confs) {
this.confs = confs;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}