即使查询有效,Hibernate也不会填充elementCollection

时间:2019-02-14 10:19:27

标签: java hibernate jpa hibernate-mapping sql-server-2017

我有一个包含用户名的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表与休眠一起连接时,我遇到了问题。在休眠状态下,userNameuserId列需要具有完全相同的值(包括大小写),否则用户没有权限。这意味着

test == test
john != JOHN
DOE  == DOE

如果用户john尝试登录,则他没有权限,因为休眠状态无法将用户名与user permission表匹配。我认为一种简单的解决方法是,让休眠状态将两个列(userNameuserId都视为大写列(至少对于联接而言),但是我找不到有关此主题的任何信息

如何告诉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;
    }

}

0 个答案:

没有答案