// Context: I'm trying to pass a lambda as a higher order function to a `runTransaction` wrapper method.
// It's failing because of "bad return type". I can't tell if my error is fundamental or syntax or both?
// Version info:
// java version "1.8.0_171"
// Java(TM) SE Runtime Environment (build 1.8.0_171-b11)
// Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)
// Error message:
// Sample.java:100: error: incompatible types: bad return type in lambda expression
// int returnValue = runTransaction(session, (Session s) -> {
// ^
// missing return value
package com.cockroachlabs;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import java.util.*;
import java.util.function.Function;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.criteria.CriteriaQuery;
public class Sample {
// Create a SessionFactory based on our hibernate.cfg.xml configuration
// file, which defines how to connect to the database.
private static final SessionFactory sessionFactory =
new Configuration()
.configure("hibernate.cfg.xml")
.addAnnotatedClass(Account.class)
.buildSessionFactory();
// Account is our model, which corresponds to the "accounts" database table.
@Entity
@Table(name="accounts")
public static class Account {
@Id
@Column(name="id")
public long id;
@Column(name="balance")
public long balance;
// Convenience constructor.
public Account(int id, int balance) {
this.id = id;
this.balance = balance;
}
// Hibernate needs a default (no-arg) constructor to create model objects.
public Account() {}
}
private static Random rand = new Random();
// static Function addAccounts(Session s1) {
// Function f = (Session s) -> {
// try {
// s.save(new Account(1, 1000));
// s.save(new Account(2, 250));
// s.save(new Account(3, 314159));
// s.getTransaction().commit();
// } catch (Exception e) {
// throw e;
// }
// };
// return f;
// }
static int runTransaction(Session session, Function fn) {
int returnValue = 0;
int retryCount = 0;
int MAX_RETRY_COUNT = 3;
String RETRY_SQL_STATE = "40001";
boolean FORCE_RETRY = false;
try {
fn.apply(session);
} catch (org.hibernate.JDBCException e) {
if (RETRY_SQL_STATE.equals(e.getSQLState())) {
session.getTransaction().rollback();
retryCount++;
int sleepMillis = (int)(Math.pow(2, retryCount) * 100) + rand.nextInt(100);
System.out.printf("Hit 40001 transaction retry error, sleeping %s milliseconds\n", sleepMillis);
try {
Thread.sleep(sleepMillis);
} catch (InterruptedException ignored) {
// Necessary to allow the retry loop to continue.
}
returnValue = -1;
} else {
returnValue = -1;
throw e;
}
} finally {
session.close();
sessionFactory.close();
}
}
public static void main(String[] args) throws Exception {
Session session = sessionFactory.openSession();
try {
// Below lambda `(Session s) -> {` fails with:
// error: incompatible types: bad return type in lambda expression
// int returnValue = runTransaction(session, (Session s) -> {
// ^
// missing return value
int returnValue = runTransaction(session, (Session s) -> { // BOOM!!!
try {
s.save(new Account(1, 1000));
s.save(new Account(2, 250));
s.save(new Account(3, 314159));
s.getTransaction().commit();
} catch (Exception e) {
throw e;
}
});
if (returnValue != -1) {
// Success!
System.out.printf("transferFunds EXIT_SUCCESS");
}
} finally {
session.close();
sessionFactory.close();
}
}
}
// gradle build
// > Task :compileJava FAILED
// /Users/rloveland/work/code/deemphasize-savepoints/java-hibernate/src/main/java/com/cockroachlabs/Sample.java:100: error: incompatible types: bad return type in lambda expression
// int returnValue = runTransaction(session, (Session s) -> {
// ^
// missing return value
// Note: /Users/rloveland/work/code/deemphasize-savepoints/java-hibernate/src/main/java/com/cockroachlabs/Sample.java uses unchecked or unsafe operations.
// Note: Recompile with -Xlint:unchecked for details.
// Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
// 1 error
// FAILURE: Build failed with an exception.
// * What went wrong:
// Execution failed for task ':compileJava'.
// > Compilation failed; see the compiler error output for details.
// * Try:
// Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
// * Get more help at https://help.gradle.org
// BUILD FAILED in 564ms
// 1 actionable task: 1 executed
// Compilation exited abnormally with code 1 at Tue Aug 13 13:55:17
Comments