我有一个包含用户名的User
表。这些用户名可以大写和小写。我还有第二张表来管理user permissions
。
假设此数据:
用户表:
userName userPassword
--------------------------
test test
john password
DOE testtest
用户权限表:
userId permissionId
-------------------------
test permission1
JOHN PERMISSION1
DOE permission2
用户权限实际上是一个枚举,并且在User
类中的映射方式如下:
@ElementCollection(targetClass = UserPermission.class, fetch = FetchType.EAGER)
@JoinTable(name = "USER_PERMISSION", joinColumns = @JoinColumn(name = "userId"))
@Enumerated(EnumType.STRING)
@Column(name = "permissionId")
@ColumnTransformer(read = "UPPER(permissionId)")
private List<UserPermission> userPermissionList;
我使用此映射来确保读取的权限始终为大写,以确保可以将其转换为实际的枚举值。
现在,在将user
表与user permission
表与休眠一起连接时,我遇到了问题。在休眠状态下,userName
和userId
列需要具有完全相同的值(包括大小写),否则用户没有权限。这意味着
test == test
john != JOHN
DOE == DOE
如果用户john
尝试登录,则他没有权限,因为休眠状态无法将用户名与user permission
表匹配。我认为一种简单的解决方法是,让休眠状态将两个列(userName
和userId
都视为大写列(至少对于联接而言),但是我找不到有关此主题的任何信息
如何告诉hibernate将发生连接的列视为UPPER()
列?
有问题的数据库是MSSQL 2017,不区分大小写,此查询的结果证明了这一点:
select * from User inner join USER_PERMISSION on userName = userId
这将导致
userName userPassword userId permissionId
------------------------------------------------------
test test test permission1
john password JOHN PERMISSION1
DOE testtest DOE permission2
编辑:
根据要求,由休眠生成的实际查询:
select
userpermis0_.userId as userId1_8_0_,
UPPER(userpermis0_.permissionId) as permissi2_8_0_
from
dbo.USER_PERMISSION userpermis0_
where
userpermis0_.userId=?
无论我怎么看,都没有理由不获取该查询的结果
编辑2:
这是我的sessionfactory配置:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"
scope="singleton">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<value>mainFirst.MATRICS</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2012Dialect</prop>
<prop key="hibernate.default_schema">dbo</prop>
<!-- <prop key="hibernate.hbm2ddl.auto">update</prop> -->
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.show_sql">true</prop>
<!-- optimize -->
<!-- <prop key="hibernate.default_batch_fetch_size">16</prop> -->
<prop key="hibernate.max_fetch_depth">3</prop>
<prop key="hibernate.jdbc.batch_size">0</prop>
<prop key="hibernate.jdbc.batch_versioned_data">true</prop>
<!-- charset -->
<prop key="hibernate.connection.CharSet">utf8</prop>
<prop key="hibernate.connection.characterEncoding">utf8</prop>
<prop key="hibernate.connection.useUnicode">true</prop>
</props>
</property>
</bean>
以及完整的类和映射:
@Entity
@Table(name = "User")
public class User {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Id
private String userName;
private String encryptedPassword;
private String firstName;
private String lastName;
private Calendar lastLoginDateTime;
private Calendar nextPasswordChangeDate;
private String emailAddress;
private String emailSignature;
private Boolean allowedToLoginFlag;
private Boolean passwordChangeRequiredFlag;
@ElementCollection(targetClass = UserPermission.class, fetch = FetchType.EAGER)
@CollectionTable(name = "USER_PERMISSION", joinColumns = @JoinColumn(name = "userId"))
@Enumerated(EnumType.STRING)
@Column(name = "permissionId")
@ColumnTransformer(read = "UPPER(permissionId)")
private List<UserPermission> userPermissionList;
public User() {
}
//ommit getter and setter and other methods
}
UserPermission枚举:
public enum UserPermission {
PERMISSION1("PERMISSION1"), PERMISSION2("PERMISSION2");
private String identifier;
UserPermission(String name) {
this.identifier = name;
}
public String getIdentifier() {
return identifier;
}
public void setIdentifier(String identifier) {
this.identifier = identifier;
}
}