Skip to content

Commit 4d9e182

Browse files
committed
HHH-8371 Consider explicit column name's "_" in alias creation
1 parent 5d1ebed commit 4d9e182

File tree

8 files changed

+353
-4
lines changed

8 files changed

+353
-4
lines changed

hibernate-core/src/main/java/org/hibernate/internal/util/StringHelper.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ private StringHelper() { /* static methods only - hide constructor */
5252
public static int lastIndexOfLetter(String string) {
5353
for ( int i=0; i<string.length(); i++ ) {
5454
char character = string.charAt(i);
55-
if ( !Character.isLetter(character) /*&& !('_'==character)*/ ) return i-1;
55+
// Include "_". See HHH-8073
56+
if ( !Character.isLetter(character) && !('_'==character) ) return i-1;
5657
}
5758
return string.length()-1;
5859
}

hibernate-core/src/main/java/org/hibernate/mapping/Column.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public String getQuotedName(Dialect d) {
111111
@Override
112112
public String getAlias(Dialect dialect) {
113113
final int lastLetter = StringHelper.lastIndexOfLetter( name );
114-
String suffix = Integer.toString(uniqueInteger) + '_';
114+
final String suffix = Integer.toString(uniqueInteger) + '_';
115115

116116
String alias = name;
117117
if ( lastLetter == -1 ) {

hibernate-core/src/test/java/org/hibernate/test/mapping/AliasTest.java

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,15 @@
2020
*/
2121
package org.hibernate.test.mapping;
2222

23+
import static org.junit.Assert.assertEquals;
24+
import static org.junit.Assert.assertNotNull;
2325
import static org.junit.Assert.assertTrue;
26+
import static org.junit.Assert.fail;
2427

2528
import java.util.Iterator;
2629

30+
import org.hibernate.HibernateException;
31+
import org.hibernate.Session;
2732
import org.hibernate.mapping.Table;
2833
import org.hibernate.testing.TestForIssue;
2934
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
@@ -40,10 +45,17 @@
4045
*
4146
* @author Brett Meyer
4247
*/
43-
@TestForIssue( jiraKey = "HHH-2448" )
4448
public class AliasTest extends BaseCoreFunctionalTestCase {
4549

50+
/**
51+
* Column aliases utilize {@link Table#getUniqueInteger()} for naming. The unique integer used to be statically
52+
* generated by the Table class, meaning it was dependent on mapping order. HHH-2448 made the alias names
53+
* deterministic by having Configuration determine the unique integers on its second pass over the Tables tree map.
54+
* AliasTest and {@link MappingReorderedAliasTest} ensure that the unique integers are the same, regardless of
55+
* mapping ordering.
56+
*/
4657
@Test
58+
@TestForIssue( jiraKey = "HHH-2448" )
4759
public void testAliasOrdering() {
4860
Iterator<Table> tables = configuration().getTableMappings();
4961
Table table1 = null;
@@ -60,9 +72,48 @@ else if ( table.getName().equals( "Table2" ) ) {
6072

6173
assertTrue( table1.getUniqueInteger() < table2.getUniqueInteger() );
6274
}
75+
76+
@Test
77+
@TestForIssue( jiraKey = "HHH-8371" )
78+
public final void testUnderscoreInColumnName() throws Throwable {
79+
final Session s = openSession();
80+
s.getTransaction().begin();
81+
82+
UserEntity user = new UserEntity();
83+
user.setName( "foo" );
84+
s.persist(user);
85+
final ConfEntity conf = new ConfEntity();
86+
conf.setConfKey("counter");
87+
conf.setConfValue("3");
88+
final UserConfEntity uc = new UserConfEntity();
89+
uc.setUser(user);
90+
uc.setConf(conf);
91+
conf.getUserConf().add(uc);
92+
s.persist(conf);
93+
94+
s.getTransaction().commit();
95+
s.clear();
96+
97+
s.getTransaction().begin();
98+
user = (UserEntity) s.get(UserEntity.class, user.getId());
99+
100+
try {
101+
s.flush();
102+
}
103+
catch ( HibernateException e ) {
104+
// original issue from HHH-8371
105+
fail( "The explicit column name's underscore(s) were not considered during alias creation." );
106+
}
107+
108+
assertNotNull( user );
109+
assertEquals( user.getName(), "foo" );
110+
111+
s.getTransaction().commit();
112+
s.close();
113+
}
63114

64115
@Override
65116
protected Class<?>[] getAnnotatedClasses() {
66-
return new Class<?>[] { Table1.class, Table2.class };
117+
return new Class<?>[] { Table1.class, Table2.class, ConfEntity.class, UserConfEntity.class, UserEntity.class };
67118
}
68119
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package org.hibernate.test.mapping;
2+
3+
import static javax.persistence.CascadeType.ALL;
4+
5+
import java.io.Serializable;
6+
import java.util.HashSet;
7+
import java.util.Set;
8+
9+
import javax.persistence.Column;
10+
import javax.persistence.Entity;
11+
import javax.persistence.FetchType;
12+
import javax.persistence.Id;
13+
import javax.persistence.IdClass;
14+
import javax.persistence.OneToMany;
15+
import javax.persistence.Table;
16+
17+
@Entity
18+
@Table(name = "CONF")
19+
@IdClass(ConfId.class)
20+
public class ConfEntity implements Serializable{
21+
22+
private static final long serialVersionUID = -5089484717715507169L;
23+
24+
@Id
25+
@Column(name = "confKey")
26+
private String confKey;
27+
28+
@Id
29+
@Column(name = "confValue")
30+
private String confValue;
31+
32+
@OneToMany(mappedBy="conf", cascade = ALL, orphanRemoval = true, fetch = FetchType.LAZY)
33+
private Set<UserConfEntity> userConf = new HashSet<UserConfEntity>();
34+
35+
public String getConfKey() {
36+
return confKey;
37+
}
38+
39+
public void setConfKey(String confKey) {
40+
this.confKey = confKey;
41+
}
42+
43+
public String getConfValue() {
44+
return confValue;
45+
}
46+
47+
public void setConfValue(String confValue) {
48+
this.confValue = confValue;
49+
}
50+
51+
public Set<UserConfEntity> getUserConf() {
52+
return userConf;
53+
}
54+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package org.hibernate.test.mapping;
2+
3+
import java.io.Serializable;
4+
5+
public class ConfId implements Serializable{
6+
7+
private static final long serialVersionUID = -6722022851594514199L;
8+
9+
private String confKey;
10+
11+
private String confValue;
12+
13+
public ConfId(){
14+
}
15+
16+
public ConfId(String confKey, String confValue) {
17+
this.confKey = confKey;
18+
this.confValue = confValue;
19+
}
20+
21+
public String getConfKey() {
22+
return confKey;
23+
}
24+
25+
public void setConfKey(String confKey) {
26+
this.confKey = confKey;
27+
}
28+
29+
public String getConfValue() {
30+
return confValue;
31+
}
32+
33+
public void setConfValue(String confValue) {
34+
this.confValue = confValue;
35+
}
36+
37+
@Override
38+
public int hashCode() {
39+
final int prime = 31;
40+
int result = 1;
41+
result = prime * result + ((confKey == null) ? 0 : confKey.hashCode());
42+
result = prime * result + ((confValue == null) ? 0 : confValue.hashCode());
43+
return result;
44+
}
45+
46+
@Override
47+
public boolean equals(Object obj) {
48+
if (this == obj)
49+
return true;
50+
if (obj == null)
51+
return false;
52+
if (getClass() != obj.getClass())
53+
return false;
54+
ConfId other = (ConfId) obj;
55+
if (confKey == null) {
56+
if (other.confKey != null)
57+
return false;
58+
} else if (!confKey.equals(other.confKey))
59+
return false;
60+
else if (confValue == null) {
61+
if (other.confValue != null)
62+
return false;
63+
} else if (!confValue.equals(other.confValue))
64+
return false;
65+
return true;
66+
}
67+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package org.hibernate.test.mapping;
2+
3+
import java.io.Serializable;
4+
5+
import javax.persistence.Entity;
6+
import javax.persistence.Id;
7+
import javax.persistence.IdClass;
8+
import javax.persistence.JoinColumn;
9+
import javax.persistence.JoinColumns;
10+
import javax.persistence.ManyToOne;
11+
import javax.persistence.Table;
12+
13+
@Entity
14+
@Table(name = "USER_CONFS")
15+
@IdClass(UserConfId.class)
16+
public class UserConfEntity implements Serializable{
17+
18+
private static final long serialVersionUID = 9153314908821604322L;
19+
20+
@Id
21+
@ManyToOne
22+
@JoinColumn(name="user_id")
23+
private UserEntity user;
24+
25+
@Id
26+
@ManyToOne
27+
@JoinColumns({
28+
@JoinColumn(name="cnf_key", referencedColumnName="confKey"),
29+
@JoinColumn(name="cnf_value", referencedColumnName="confValue")})
30+
private ConfEntity conf;
31+
32+
public ConfEntity getConf() {
33+
return conf;
34+
}
35+
36+
public void setConf(ConfEntity conf) {
37+
this.conf = conf;
38+
}
39+
40+
41+
public UserEntity getUser() {
42+
return user;
43+
}
44+
45+
public void setUser(UserEntity user) {
46+
this.user = user;
47+
}
48+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package org.hibernate.test.mapping;
2+
3+
import java.io.Serializable;
4+
5+
6+
7+
public class UserConfId implements Serializable{
8+
9+
private static final long serialVersionUID = -161134972658451944L;
10+
11+
private Long user;
12+
13+
private ConfId conf;
14+
15+
public UserConfId(){
16+
}
17+
18+
public UserConfId(Long user, ConfId conf) {
19+
this.user = user;
20+
this.conf = conf;
21+
}
22+
23+
public Long getUser() {
24+
return user;
25+
}
26+
27+
public void setUser(Long user) {
28+
this.user = user;
29+
}
30+
31+
32+
public ConfId getConf() {
33+
return conf;
34+
}
35+
36+
public void setConf(ConfId conf) {
37+
this.conf = conf;
38+
}
39+
40+
@Override
41+
public int hashCode() {
42+
final int prime = 31;
43+
int result = 1;
44+
result = prime * result + ((conf == null) ? 0 : conf.hashCode());
45+
result = prime * result + ((user == null) ? 0 : user.hashCode());
46+
return result;
47+
}
48+
49+
@Override
50+
public boolean equals(Object obj) {
51+
if (this == obj)
52+
return true;
53+
if (obj == null)
54+
return false;
55+
if (getClass() != obj.getClass())
56+
return false;
57+
UserConfId other = (UserConfId) obj;
58+
if (conf == null) {
59+
if (other.conf != null)
60+
return false;
61+
} else if (!conf.equals(other.conf))
62+
return false;
63+
if (user == null) {
64+
if (other.user != null)
65+
return false;
66+
} else if (!user.equals(other.user))
67+
return false;
68+
return true;
69+
}
70+
}

0 commit comments

Comments
 (0)