Java.Util.Stream with Resultset

How to write java.util.stream.Stream to StreamingResponseBody output stream

Finally, I resolved the problem by using the service layer. Initially, I was writing the complete logic in Controller Class which was creating the issue.

Controller Class -

@RestController
@RequestMapping("/api")
public class UsersController {
@Autowired
private UserService service;

@GetMapping(value = "/userstream")
public ResponseEntity<StreamingResponseBody> fetchUsersStream() {

StreamingResponseBody stream = this::writeTo;

return new ResponseEntity<>(stream, HttpStatus.OK);
}

private void writeTo(OutputStream outputStream) {
service.writeToOutputStream(outputStream);
}
}

Service Class -

@Service
public class UserService {

@Autowired
private UsersRepository usersRepository;

@Transactional(readOnly = true)
public void writeToOutputStream(final OutputStream outputStream) {
try (Stream<UsersEntity> usersResultStream = usersRepository.findAllByCustomQueryAndStream()) {
try (ObjectOutputStream oos = new ObjectOutputStream(outputStream)) {

usersResultStream.forEach(emp -> {
try {
oos.write(emp.toString().getBytes());
} catch (IOException e) {
e.printStackTrace();
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

Complete Code is available at github - https://github.com/bagesh2050/HttpResponseStreamingDemo

Still, I am willing for suggestions related to Http Streaming. Please provide if you have better ideas.

How to use Group by on a result set response

Use the groupingBy collector with the first element of the list as the key, and then pass the second element to the mapping downstream collector. Finally use the toList collector to accumulate the values into a List. Since you have different types such as Long, String et.al. It's worth writing a generic method for the conversion and use it for all the types. Here's how it looks.

private static <T> Map<T, List<T>> keyValListToMap(List<List<T>> source) {
return source.stream()
.collect(Collectors.groupingBy(l -> l.get(0),
Collectors.mapping(l -> l.get(1), Collectors.toList())));
}

And here's your client code.

Map<Long, List<Long>> result = keyValListToMap(resultSet);

SQLServerException: The result set is closed when using Streams as return type

I've found that making the service method that is calling the repository be inside of a transaction gets rid of this error for me.

@Transactional(readOnly=true)
public List<Results> myServiceMethod() {
return repo.findByContactid("12345").map(c->c.getName()).collect(toList());
}

Stream fetched from Postgres with jOOQ not returning results from class

The whole point of the Java Stream API is for such a stream to be consumed at most once. It does not have any buffering feature, nor does it support a push based streaming model like reactive stream implementations do.

You could add another API to your stack, such as e.g. Reactor (there are others, but since you're already using Spring...), which supports buffering and replaying streams to several consumers, but that has nothing to do with jOOQ directly and will heavily influence your application's architecture.

Notice that jOOQ's ResultQuery extends org.reactivestreams.Publisher and JDK 9's Flow.Publisher for better interoperability with such reactive streams.



Related Topics



Leave a reply



Submit