Java 使用相同的JPQL查询处理不同的模式名称

Java 使用相同的JPQL查询处理不同的模式名称,java,postgresql,spring-boot,spring-data-jpa,jpql,Java,Postgresql,Spring Boot,Spring Data Jpa,Jpql,我目前正在开发一个基于Spring Boot的微服务应用程序,它使用JPA进行DB持久化。使用的数据库是PostgreSQL。为了获得序列hotel_id_seq的最后一个值,使用了以下方法 问题出现在一个新的变更请求中,该请求要求在不同的环境中部署服务,在这种情况下,门户客户名称将构成schemaname,并且必须附加(代替“schemaname”)在每个实例上。当我使用本机查询时,是否有方法将动态customername容纳到查询中?是否可以用JPQL重写此查询以避免这种情况 这些是我在St

我目前正在开发一个基于Spring Boot的微服务应用程序,它使用JPA进行DB持久化。使用的数据库是PostgreSQL。为了获得序列hotel_id_seq的最后一个值,使用了以下方法

问题出现在一个新的变更请求中,该请求要求在不同的环境中部署服务,在这种情况下,门户客户名称将构成schemaname,并且必须附加(代替“schemaname”)在每个实例上。当我使用本机查询时,是否有方法将动态customername容纳到查询中?是否可以用JPQL重写此查询以避免这种情况

这些是我在Stackoverflow上发现的一些相关问题,但它们没有提供我问题的具体答案

模型类

package travel.travelos.hotel.setup.entity.local;

import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "hotel")
public class Hotel implements java.io.Serializable {

    private long id;

        //Ommited for Clarity

    public Hotel() {
    }

    public Hotel(Long hotelId) {
        this.id = hotelId;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", unique = true, nullable = false)
    public long getId() {
        return this.id;
    }

    public void setId(long id) {
        this.id = id;
    }

       //Ommited for Clarity

     }
package travel.travelos.hotel.setup.main.repository;

import java.util.List;

import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;

import rezg.rezos.hotel.setup.entity.local.Hotel;

public interface HotelRepository extends PagingAndSortingRepository<Hotel, Long> {

  //Note:SchemaName would vary accordnig to portal customers name
  @Query(nativeQuery = true, value = "SELECT last_value FROM schemaName_hotel_setup.hotel_id_seq")
    public Long getLastSequence();

}
Jpa存储库

package travel.travelos.hotel.setup.entity.local;

import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "hotel")
public class Hotel implements java.io.Serializable {

    private long id;

        //Ommited for Clarity

    public Hotel() {
    }

    public Hotel(Long hotelId) {
        this.id = hotelId;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", unique = true, nullable = false)
    public long getId() {
        return this.id;
    }

    public void setId(long id) {
        this.id = id;
    }

       //Ommited for Clarity

     }
package travel.travelos.hotel.setup.main.repository;

import java.util.List;

import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;

import rezg.rezos.hotel.setup.entity.local.Hotel;

public interface HotelRepository extends PagingAndSortingRepository<Hotel, Long> {

  //Note:SchemaName would vary accordnig to portal customers name
  @Query(nativeQuery = true, value = "SELECT last_value FROM schemaName_hotel_setup.hotel_id_seq")
    public Long getLastSequence();

}
更新:备用修复程序

我设法对查询的执行方式进行了一些修改,并动态地附加了门户名称,从而在HotelServiceImpl级别而不是像以前那样在HotelRepository中处理此场景。虽然此变通方法工作正常,但实现会影响关注点的分离。此解决方案将如何影响再往前走?我会很感激你的帮助

package rezg.rezos.hotel.setup.service;

@Component
@Transactional
@PropertySource("classpath:application.yml")
class HotelServiceImpl implements HotelStandardInfoService{



    private HotelRepository hotelRepository;

        @Autowired
        private Messages messages;

        @Autowired
        private HttpSession session;

        @Value("${portal.name}")
        private String portalName;

        @Autowired
        private EntityManager entityManager;

          //Ommited for Clarity

            @Override
        public String generateHotelCode() throws Exception {
            System.out.println("portalName : "+ portalName);
            Query q = entityManager.createNativeQuery("SELECT last_value FROM "+portalName +"_"+"hotel_setup.hotel_id_seq");
            Long nextHotelId=((BigInteger)q.getSingleResult()).longValue();
            System.out.println("nextHotelId : "+ nextHotelId);

          /*Long nextHotelId = hotelRepository.getLastSequence();*/
    ;
有用的参考资料


就我个人而言,我从不指定模式,除非我使用具有相同连接的多个模式,这是我尽量避免的。当您获得序列值时,您不能只使用活动模式吗?当您达到该程度时,您的连接的正确模式可能已经处于活动状态?您可以更改数据库的
搜索路径
用户避免使用完全限定的表名。我看不出关注点分离的问题。您的关注点是数据库访问,这在您的实现中得到了很好的处理。如果您的意思是希望使用JPQL而不是本机查询,那么在执行qu之前,也许您可以使用在连接中设置架构正如这里所解释的