小编mru*_*nak的帖子

使用Spring JPA/Hibernate进行条件插入

我正在开发一个在集群环境中运行的项目,其中有许多节点和一个数据库.该项目使用Spring-data-JPA(1.9.0)和Hibernate(5.0.1).我无法解决如何防止重复行问题.

例如,这是一个简单的表格

@Entity
@Table(name = "scheduled_updates")
public class ScheduledUpdateData {
    public enum UpdateType {
        TYPE_A,
        TYPE_B
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private UUID id;

    @Column(name = "type", nullable = false)
    @Enumerated(EnumType.STRING)
    private UpdateType type;

    @Column(name = "source", nullable = false)
    private UUID source;
}
Run Code Online (Sandbox Code Playgroud)

重要的是有一个UNIQUE(type, source)约束.

当然,匹配示例存储库:

@Repository
public class ScheduledUpdateRepository implements JpaRepository<ScheduledUpdateData, UUID> {
    ScheduledUpdateData findOneByTypeAndSource(final UpdateType type, final UUID source);

    //...
}
Run Code Online (Sandbox Code Playgroud)

这个例子的想法是,系统的某些部分可以插入行以安排定期运行的事件,在所述运行之间任意次数.无论什么东西实际运行,它都不必担心两次操作相同的东西.

如何编写有条件地插入此表的服务方法?我已经试过了几件事情不工作是:

  1. 查找>操作 - 服务方法将使用存储库查看条目是否已存在,然后根据需要更新找到的条目或保存新条目.这不起作用.
  2. 如果失败,请尝试插入>更新 - 服务方法将尝试插入,由于唯一约束而捕获异常,然后执行更新.这不起作用,因为事务已经处于回滚状态,并且不能在其中进行进一步的操作.
  3. 使用"INSERT …

java orm hibernate jpa spring-data-jpa

8
推荐指数
1
解决办法
2997
查看次数

Spring Session 和 Spring Security - 会话超时处理不起作用

当尝试将 spring-session 添加到具有 spring-security 的现有 Spring MVC 项目时,我得到以下行为(编辑:tomcat 的 session-timeout 设置为 1 分钟以进行测试):

  • 使用 web.xml 中的 springSessionRepositoryFilter 过滤器注释掉,我在一分钟不活动后正确启动到登录屏幕
  • 当 web.xml 中的 springSessionRepositoryFilter 过滤器处于活动状态时,我可以在最后一次活动后至少 5 分钟继续使用该应用程序

除此之外,一切似乎都按预期工作 - 会话在 redis 中持续存在并跨 webapp 重新启动,并且手动注销正确地使会话无效。

我的一些配置片段 - 这是 spring-security 的无效会话处理程序配置,这将导致过期的会话被重定向到登录页面:

...
<beans:bean id="sessionManagementFilter" class="org.springframework.security.web.session.SessionManagementFilter">
    <beans:constructor-arg name="securityContextRepository">
        <beans:bean class="org.springframework.security.web.context.HttpSessionSecurityContextRepository"/>
    </beans:constructor-arg>
    <beans:property name="invalidSessionStrategy">
        <beans:bean class="my.CustomInvalidSessionStrategy"/>
    </beans:property>
</beans:bean>
...
<http>
    ...
    <custom-filter position="SESSION_MANAGEMENT_FILTER" ref="sessionManagementFilter"/>
    ...
    <logout delete-cookies="true" invalidate-session="true" logout-url="/signout.html" success-handler-ref="logoutSuccessHandler"/>
</http>
Run Code Online (Sandbox Code Playgroud)

web.xml 的过滤器链如下所示:

<filter>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> …
Run Code Online (Sandbox Code Playgroud)

spring-security spring-session

6
推荐指数
1
解决办法
1660
查看次数

Hibernate/JPA 可选的一对一双向映射

我有两个表,每个表都用于描述有关对象的信息,但来自两个不同的系统。因此,给定的对象可以存在于其中一个、另一个或两者中。

service_A
---------------
service_A_pkey UUID NOT NULL PRIMARY KEY,
common_identifier TEXT NOT NULL,
<more columns to store data>
Run Code Online (Sandbox Code Playgroud)

和

service_B
---------------
service_B_pkey UUID NOT NULL PRIMARY KEY,
common_identifier TEXT NOT NULL,
<more columns to store data>
Run Code Online (Sandbox Code Playgroud)

理想情况下,我希望两个 JPA 实体都包含彼此的引用(如果存在),这样如果我使用任一存储库来查找给定服务的对象,它就会附带来自其他服务的“额外”信息,而无需执行以下操作更多手动查找。从网络上的其他示例来看,我认为这样的方法会起作用:

@Entity
@Table(name = "service_A")
public class ServiceAData {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "service_A_pkey")
    private UUID pkey;

    @Column(name = "common_identifier", nullable = false)
    private String commonIdentifier;

    @OneToOne(optional = true, mappedBy = "serviceAData")
    private ServiceBData serviceBData;
}

@Entity
@Table(name = "service_B") …
Run Code Online (Sandbox Code Playgroud)

java hibernate jpa

5
推荐指数
1
解决办法
5501
查看次数

抛出异常作为反应流验证的最正确方法

我有一个反应流,我希望在其中一步应用验证检查,如果失败,将引发异常。是否有一种普遍接受的风格来做到这一点?从我可以告诉我有三种选择(使用Mono)的then(),filter()和map()。

  1. filter()最接近我想要的流,因为我实际上并没有尝试更改流中的数据类型或切换到另一个流。但是,过滤器应该返回真/假来过滤掉项目,所以总是返回真有点傻。
  2. then() 让我专门选择错误/成功排放,但有时对于这种类型的验证,我无法轻松地将其拆分为自己的私有方法,并且样板使流声明更难以阅读。
  3. map()与 using 几乎相同filter(),除了您总是在输入中返回而不是 TRUE。

作为一个非常人为的例子,考虑一个服务,它有 0 个或多个字母的列表要发送给一个人:

public interface Person {
    UUID getId();
    List<String> getKnownLanguages();
}

public interface Letter {
    String getLanguage();
}

public class LetterService {
    private Letter findOneLetterForPerson(final UUID id) { /* ... */ }

    private void removeLetter(final Letter letter) { /* ... */ }
}
Run Code Online (Sandbox Code Playgroud)

创建如下所示的方法的更好选择是什么:

public Mono<Optional<Letter>> getNextValidLetterForPerson(final Person person) {
    return Mono.just(person)
               .and(this::getNextLetterForPerson)

               /////////////////////////////////////////
               //
               .filter(this::validatePersonCanReadLetter1)
               .map(Tuple2::getT2)
               //
               // …
Run Code Online (Sandbox Code Playgroud)

reactive-programming project-reactor

5
推荐指数
1
解决办法
4848
查看次数

无法在 RedisCacheConfiguration 中使用任何对象作为 KeySerializer

一组较旧的代码RedisCacheManager针对RedisTemplate产品中使用的大量缓存进行了配置。特别是模板会经常声明非字符串类型的键序列化器,例如:

<property name="keySerializer">
    <bean class="org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer">
        <constructor-arg value="java.lang.Long"/>
    </bean>
</property>
Run Code Online (Sandbox Code Playgroud)

(有时是 UUID)。当希望使用 Springboot 升级/转换到更新版本时RedisCacheManagerBuilder,配置序列化器的唯一方法似乎是通过RedisCacheConfiguration硬编码来获取SerializationPair<String>for 键。

这种强制输入字符串是否有原因?

redis spring-boot spring-cache

5
推荐指数
0
解决办法
241
查看次数

如果启动时没有可用的代理,Spring Integration Kafka 3.0.1 -&gt; 3.1.2 测试现在无法启动

在将一个项目从 Springboot 2.0 升级到 2.1 的时候,我们也spring-kafka-integration从 3.0.1升级到了 3.2.1。在这样做时,我们的测试现在都无法启动,原因如下:

org.apache.kafka.clients.NetworkClient   : [Consumer clientId=consumer-1, groupId=x] Connection to node -1 could not be established. Broker may not be available.
org.apache.kafka.clients.NetworkClient   : [Consumer clientId=consumer-1, groupId=x] Connection to node -1 could not be established. Broker may not be available.
org.apache.kafka.clients.NetworkClient   : [Consumer clientId=consumer-1, groupId=x] Connection to node -1 could not be established. Broker may not be available.
...
org.springframework.context.ApplicationContextException: Failed to start bean 'eventInboundFlow.kafka:message-driven-channel-adapter#0'; nested exception is org.apache.kafka.common.errors.TimeoutException: Timeout expired while fetching topic …
Run Code Online (Sandbox Code Playgroud)

java spring-boot spring-kafka

4
推荐指数
1
解决办法
1400
查看次数

NoClassDefFoundError:scala/math/Ordering with spring-kafka-test 2.5.7

我有一个提供 JUnit 5 扩展的小型库EmbeddedKafkaBroker,它试图@DirtiesContext通过在测试之间将偏移重置为最新而不是丢弃整个上下文来提高性能,而不仅仅是使用。

我的 build.gradle 是:

import org.springframework.boot.gradle.plugin.SpringBootPlugin

plugins {
    id 'org.springframework.boot' version '2.3.5.RELEASE' apply false
    id 'io.spring.dependency-management' version '1.0.10.RELEASE'
}

dependencyManagement {
    imports {
        mavenBom SpringBootPlugin.BOM_COORDINATES
    }
}

sourceCompatibility = '1.8'

dependencies {
    implementation 'org.junit.jupiter:junit-jupiter-api'
    implementation 'org.springframework.kafka:spring-kafka'
    implementation 'org.springframework.kafka:spring-kafka-test'
    compileOnly 'org.springframework.integration:spring-integration-core'

    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testRuntime 'org.springframework.integration:spring-integration-core'
    testRuntime 'org.junit.jupiter:junit-jupiter-engine'
}
Run Code Online (Sandbox Code Playgroud)

这解决了spring-kafka:2.5.7在2.12. 当扩展尝试启动 时EmbeddedKafkaBroker,我收到以下异常:

java.lang.NoClassDefFoundError: scala/math/Ordering$$anon$7

    at kafka.api.ApiVersion$.orderingByVersion(ApiVersion.scala:45)
    at kafka.api.ApiVersion.compare(ApiVersion.scala:139)
    at kafka.api.ApiVersion.compare$(ApiVersion.scala:138)
    at kafka.api.KAFKA_2_5_IV0$.compare(ApiVersion.scala:339)
    at kafka.api.KAFKA_2_5_IV0$.compare(ApiVersion.scala:339)
    at scala.math.Ordered.$greater$eq(Ordered.scala:91)
    at scala.math.Ordered.$greater$eq$(Ordered.scala:91)
    at …
Run Code Online (Sandbox Code Playgroud)

java spring scala spring-kafka

4
推荐指数
1
解决办法
2525
查看次数

Netty 4(A1) - 具有多个处理程序的AttributeMap

我正在尝试使用ChannelContext.attr()方法将对象从一个处理程序传递到另一个处理程序:

private class TCPInitializer extends ChannelInitializer<SocketChannel>
{
    @Override
    public void initChannel(final SocketChannel ch) throws Exception
    {
        ChannelPipeline pipeline = ch.pipeline();

        pipeline.addLast(new ReadTimeoutHandler(mIdleTimeout));
        pipeline.addLast(new HostMappingHandler<SyslogHandler>(mRegisteredClients,
                                                               mChannels));
        pipeline.addLast(new DelimiterBasedFrameDecoder(MAX_FRAME_SIZE,
                         Delimiters.lineDelimiter()));
        pipeline.addLast(new Dispatcher());
    }
}
Run Code Online (Sandbox Code Playgroud)

HostMappingHandler是一个将主机映射到数据的模板类:

public class HostMappingHandler<T> extends ChannelStateHandlerAdapter
{

    public static final AttributeKey<HostMappedObject> HOST_MAPPING =
        new AttributeKey<HostMappedObject>("HostMappingHandler.attr");


    private final ChannelGroup mChannels;
    private final Map<String, T> mMap;


    public HostMappingHandler(Map<String, T> registrations,
                              ChannelGroup channelGroup)
    {
        mChannels = channelGroup;
        mMap = registrations;
    }

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception
    {
        SocketAddress addr …
Run Code Online (Sandbox Code Playgroud)

netty

2
推荐指数
1
解决办法
3732
查看次数