У меня есть 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
пытается войти в систему, у него нет разрешений, потому что hibernate не может сопоставить имя пользователя с таблицей user permission
.Я подумал, что можно было бы легко обойтись, если бы hibernate рассматривал оба столбца (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
РЕДАКТИРОВАНИЕ:
По запросу, фактический запрос, сгенерированныйhibernate:
select
userpermis0_.userId as userId1_8_0_,
UPPER(userpermis0_.permissionId) as permissi2_8_0_
from
dbo.USER_PERMISSION userpermis0_
where
userpermis0_.userId=?
Независимо от того, как я на это смотрю, не должно быть никаких причин вообще не получать результаты для этого запроса
EDIT 2:
ЭтоМоя сессия: # 1054 *
<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;
}
}