Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用JPA将两个类映射到一个表,以加快spring security UserDetailsService的速度_Java_Spring_Hibernate_Spring Mvc_Jpa - Fatal编程技术网

Java 使用JPA将两个类映射到一个表,以加快spring security UserDetailsService的速度

Java 使用JPA将两个类映射到一个表,以加快spring security UserDetailsService的速度,java,spring,hibernate,spring-mvc,jpa,Java,Spring,Hibernate,Spring Mvc,Jpa,我想使用Spring、JPA和Hibernate创建一个安全的restful服务 必须保护每个端点,为此,我使用特定的UserDetails服务使用spring安全性,如spring安全文档中所述: 这里的要点是:由于每个请求都将经过身份验证,这意味着对于每个请求,my UserDetails服务将从我的数据库中加载一个用户,并需要获取其密码和角色 默认的JdbcDaoImpl使用2个请求来查找用户及其角色。 我不使用它,因为: 我希望在我的业务控制器使用UserDetails对象时,将我的

我想使用Spring、JPA和Hibernate创建一个安全的restful服务

必须保护每个端点,为此,我使用特定的UserDetails服务使用spring安全性,如spring安全文档中所述:

这里的要点是:由于每个请求都将经过身份验证,这意味着对于每个请求,my UserDetails服务将从我的数据库中加载一个用户,并需要获取其密码和角色

默认的JdbcDaoImpl使用2个请求来查找用户及其角色。 我不使用它,因为:

  • 我希望在我的业务控制器使用UserDetails对象时,将我的用户Id放在UserDetails对象中
  • 我希望我的用户只加载一个请求
我的用户业务对象看起来像:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "aa_user")
public class User
{
   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   Long id;

   @NotNull
   @Column(unique = true)
   protected String login;

   protected String password;

   @ManyToMany(targetEntity = Role.class)
   protected List<Role> roles;

   //getter/setter
}
我有很多用户子类(比如Seller,…),它们与出于业务目的而急切获取的其他对象有关联,
userRepository.findByLogin(username)
生成3个或更多重连接,以提供正确的完整获取用户对象(当然这是“正常的”),但是我只需要一个只初始化用户字段的light查询

根据这一问题: 我想做的事情似乎很复杂,但我发现我可以将
@polymorphics
Hibernate注释与
PolymorphismType.EXPLICIT

@polymorphics
不符合JPA,是我业务逻辑的一部分,或者需要重构很多查询

为了避免这种情况,我在同一个表上添加了第二个映射类:

@Entity
@Table(name = "aa_user")
public class LightUser implements SimpleUser
{  
   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   Long id;

   @NotNull
   @Column(unique = true)
   protected String login;

   protected String password;

   @ManyToMany(targetEntity = Role.class)
   protected List<Role> roles;

   //getter
}
@实体
@表(name=“aa_用户”)
公共类LightUser实现SimpleUser
{  
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
长id;
@NotNull
@列(唯一=真)
受保护的字符串登录;
受保护的字符串密码;
@ManyToMany(targetEntity=Role.class)
受保护的列表角色;
//吸气剂
}
和我的存储库:

public interface UserRepository extends JpaRepository<User, Long>
{
    @Query("SELECT u FROM User u JOIN FETCH u.roles where u.login = :login")
    User findByLogin(@Param("login") String login);
}
public interface LightUserRepository extends JpaRepository<User, Long>
{
    @Query("SELECT u FROM LightUser u JOIN FETCH u.roles where u.login = :login")
    LightUser findByLogin(@Param("login") String login);
}
公共界面LightUserRepository扩展了JpaRepository
{
@查询(“从LightUser中选择u u加入获取u.roles,其中u.login=:login”)
LightUser findByLogin(@Param(“login”)字符串login);
}
User
LightUser
使用my
UserDetailsImpl
所需的所有getter实现相同的
SimpleUser
接口

现在,
lightUserRepository.findByLogin(用户名)
使最智能的查询成为可能,并且只得到我想要的

我还有问题:

  • 它符合JPA吗
  • hbm2ddl.SchemaExport
    工作,但尝试在表
    aa_user
    和角色表之间放置两次相同的外键。如何避免这种情况
  • 如果我可以使用与
    PolymorphismType.EXPLICIT
    相同的行为进行查询,那么编写代码时可能不会那么痛苦。有人知道这是否可能吗
  • LightUser能否成为“只读”对象以避免错误

您是否尝试过使用左连接而不是连接获取来获得延迟加载?此连接工作正常,我不想要的连接位于此处未显示的用户子类中。我相信JPA版本的
@polymorphics
@heritation
。它允许您使用单表或联接多表。众所周知,Joined存在一些性能问题。如果使用单表,则该表将包含所有字段,并且这些字段中允许为空,因此可能会丢失一些数据完整性强制。单个表要求您在父对象上指定一个
@DiscriminatorColumn
,在子对象上指定一个
@DiscriminatorValue
,以标识JPA需要构建的对象。此处的更多信息:
@polymorphics
@heritation
的目标不同:-
@heritation
正如您所解释的,更改JPA在DB中存储对象的方式,实际上会对性能产生影响,但在从DB加载对象时不阻止自动多态性-
@polymorphics
仅适用于Hibernate,并且在从DB加载对象时可以防止自动多态性。看,我所做的只是使用
public interface LightUserRepository extends JpaRepository<User, Long>
{
    @Query("SELECT u FROM LightUser u JOIN FETCH u.roles where u.login = :login")
    LightUser findByLogin(@Param("login") String login);
}