How I Fixed MyBatis <choose> Errors, Groovy AtomicInteger Bugs, and Bash Startup Issues

In this technical diary I walk through three real‑world problems I hit while integrating MyBatis SQL fragments, debugging Groovy constant class compatibility, and crafting a reliable Bash startup script for Java services, sharing the root causes, error messages, and step‑by‑step fixes.

FunTester
FunTester
FunTester
How I Fixed MyBatis <choose> Errors, Groovy AtomicInteger Bugs, and Bash Startup Issues

MyBatis <choose> Syntax Error

During integration testing a MyBatis mapper used a <choose> element to select different WHERE clauses based on the parameter type. The when branch for type == 2 omitted the leading AND keyword, so the generated SQL became: ... WHERE t.id = #{testQuery} When the preceding clause already contained conditions, the missing AND caused a MySQL syntax error such as:

java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax ... near 't.id = '123''

Fix: add the missing AND before the condition in the type == 2 branch.

<choose>
    <when test="type == 1">
        AND t.name LIKE CONCAT('%', #{testQuery}, '%')
    </when>
    <when test="type == 2">
        AND t.id = #{testQuery}
    </when>
</choose>

Groovy Compatibility Issue with AtomicInteger

A constants class defines two static AtomicInteger fields:

public static AtomicInteger RUN_MARK = new AtomicInteger(getMark() % 100_000_000);
public static AtomicInteger COLLECTION_MARK = new AtomicInteger(RUN_MARK.get() / 100);

When the class is compiled/run under Groovy, numeric literals are treated as java.math.BigDecimal. Groovy therefore attempts to invoke the non‑existent constructor AtomicInteger(BigDecimal), resulting in:

groovy.lang.GroovyRuntimeException: Could not find matching constructor for: java.util.concurrent.atomic.AtomicInteger(BigDecimal)

Work‑arounds:

Explicitly cast literals to int in Groovy code, e.g. (int)100_000_000. This may still fail if the expression involves method calls returning BigDecimal.

Rewrite the constants class in plain Java (or compile it with javac) so that Groovy loads the already‑compiled bytecode. The Java version works without error.

Key lesson: avoid initializing AtomicInteger directly with numeric literals in Groovy source; either use explicit int casts or keep the class in Java.

IntelliJ Remote Host Deployment

When deploying JAR/WAR files to physical servers, the IntelliJ “Remote Host” tool can synchronize files via SFTP/SSH. Required steps:

Open Tools → Deployment → Configuration and add a new SFTP server (host, port, username, password/key).

In the Project view, enable the Remote Host tool window (View → Tool Windows → Remote Host).

Click the “Activate” button in the Remote Host toolbar to make the configured server the active target.

Drag the built JAR/WAR file from the local project pane to the remote directory, or use the “Upload” action.

Forgetting to activate the server disables the upload button, which caused a half‑hour delay in the original workflow.

IntelliJ Remote Host configuration
IntelliJ Remote Host configuration

Multi‑function Bash Service Management Script

The following Bash script provides start, stop, restart, and status commands for a Java application packaged as family-qa.jar. Improvements over a naïve implementation include:

Checking whether the process is already running before starting.

Using kill -9 to force termination when a graceful stop does not succeed.

Displaying colored status messages.

Running the Java process with nohup and common JVM options.

#!/bin/bash
version="1.0.1"
appName="family-qa.jar"

function start() {
  count=$(ps -ef | grep java | grep "$appName" | wc -l)
  if [ $count -ne 0 ]; then
    echo "Maybe $appName is running, please check it..."
  else
    echo "Starting $appName..."
    nohup java -jar "./$appName" -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError -Xms2G -Xmx2G > /dev/null 2>&1 &
  fi
}

function stop() {
  appId=$(ps -ef | grep java | grep "$appName" | awk '{print $2}')
  if [ -z "$appId" ]; then
    echo "Maybe $appName not running, please check it..."
  else
    echo "Stopping $appName (PID $appId)..."
    kill -9 "$appId"
  fi
}

function restart() {
  stop
  for i in {5..1}; do
    echo -n "$i "
    sleep 1
  done
  echo "0"
  start
}

function status() {
  appId=$(ps -ef | grep java | grep "$appName" | awk '{print $2}')
  if [ -z "$appId" ]; then
    echo -e "\033[31mNot running\033[0m"
  else
    echo -e "\033[32mRunning [PID $appId]\033[0m"
  fi
}

function usage() {
  echo "Usage: $0 {start|stop|restart|status}"
  exit 1
}

case "$1" in
  start)   start ;;
  stop)    stop ;;
  restart) restart ;;
  status)  status ;;
  *)       usage ;;
esac

This script can be placed on each server and invoked directly, reducing manual errors and providing immediate feedback on service state.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaSQLDevOpsMyBatisBashGroovy
FunTester
Written by

FunTester

10k followers, 1k articles | completely useless

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.