Hibernate не заполняет elementCollection, даже если запрос действителен - PullRequest
0 голосов
/ 14 февраля 2019

У меня есть 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;
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...