Merge pull request #710 from KyleAure/707-fix-isIntegralNumber

707 fix is integral number
diff --git a/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java b/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java
index f44999b..f70210e 100644
--- a/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java
+++ b/src/main/java/org/eclipse/yasson/internal/jsonstructure/JsonStructureToParserAdapter.java
@@ -141,7 +141,7 @@
         JsonStructureIterator iterator = iterators.peek();
         JsonValue value = iterator.getValue();
         if (value.getValueType() != JsonValue.ValueType.NUMBER) {
-            throw iterator.createIncompatibleValueError();
+            throw new IllegalStateException(iterator.createIncompatibleValueError().getMessage());
         }
         return (JsonNumber) value;
     }
diff --git a/src/test/java/org/eclipse/yasson/jsonstructure/Issue707.java b/src/test/java/org/eclipse/yasson/jsonstructure/Issue707.java
new file mode 100644
index 0000000..c9a9836
--- /dev/null
+++ b/src/test/java/org/eclipse/yasson/jsonstructure/Issue707.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2026 Contributors to the Eclipse Foundation
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+package org.eclipse.yasson.jsonstructure;
+
+import jakarta.json.bind.annotation.JsonbTypeDeserializer;
+import jakarta.json.bind.serializer.DeserializationContext;
+import jakarta.json.bind.serializer.JsonbDeserializer;
+import jakarta.json.stream.JsonParser;
+import java.lang.reflect.Type;
+import java.util.Objects;
+
+/**
+ * Test resources for Issue #707: YassonParser.isIntegralNumber throws JsonbException 
+ * instead of IllegalStateException.
+ * 
+ * This replicates the user's scenario where they want to handle both numeric and 
+ * string IDs by catching IllegalStateException when the value is not a number.
+ */
+public class Issue707 {
+    
+    /**
+     * Simple ID wrapper that can be created from either a long or a string.
+     */
+    public static class RequestId {
+        private final String value;
+        
+        private RequestId(String value) {
+            this.value = value;
+        }
+        
+        public static RequestId of(long id) {
+            return new RequestId(String.valueOf(id));
+        }
+        
+        public static RequestId of(String id) {
+            return new RequestId(id);
+        }
+        
+        public String getValue() {
+            return value;
+        }
+        
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            RequestId requestId = (RequestId) o;
+            return Objects.equals(value, requestId.value);
+        }
+        
+        @Override
+        public int hashCode() {
+            return Objects.hash(value);
+        }
+        
+        @Override
+        public String toString() {
+            return "RequestId{" + value + "}";
+        }
+    }
+    
+    /**
+     * Container class that uses a custom deserializer for the ID field.
+     */
+    public static class Request {
+        private RequestId id;
+        
+        @JsonbTypeDeserializer(RequestIdDeserializer.class)
+        public RequestId getId() {
+            return id;
+        }
+        
+        public void setId(RequestId id) {
+            this.id = id;
+        }
+    }
+    
+    /**
+     * Custom deserializer that handles both numeric and string IDs.
+     * This is the exact pattern from the issue report.
+     */
+    public static class RequestIdDeserializer implements JsonbDeserializer<RequestId> {
+        @Override
+        public RequestId deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) {
+            RequestId id = null;
+            try {
+                // Try to read as a number first
+                if (parser.isIntegralNumber()) {
+                    id = RequestId.of(parser.getLong());
+                } else {
+                    // Not an integral number, but is still a number
+                    id = RequestId.of(parser.getBigDecimal().toString());
+                }
+            } catch (IllegalStateException e) {
+                id = RequestId.of(parser.getString());
+            }
+            return id;
+        }
+    }
+}
+
diff --git a/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java b/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java
index f148600..8cf1779 100644
--- a/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java
+++ b/src/test/java/org/eclipse/yasson/jsonstructure/JsonStructureToParserAdapterTest.java
@@ -322,4 +322,69 @@
         assertEquals("test1, test2", tags);
     }
 
+    /**
+     * Test for Issue #707: isIntegralNumber() should throw IllegalStateException, not JsonbException
+     * when called on a non-numeric value.
+     *
+     * This test verifies that the user's code pattern from the issue works correctly:
+     * - When the value is a string, isIntegralNumber() throws IllegalStateException
+     * - The exception can be caught and the value read as a string
+     */
+    @Test
+    public void isIntegralNumberThrowsIllegalStateException() {
+        // Test with string ID - should catch IllegalStateException and handle gracefully
+        // This test uses fromJsonStructure to exercise JsonStructureToParserAdapter
+        JsonObjectBuilder objectBuilder = jsonProvider.createObjectBuilder();
+        objectBuilder.add("id", "abc123");
+        JsonObject jsonObject = objectBuilder.build();
+        
+        YassonJsonb jsonb = (YassonJsonb) JsonbBuilder.create();
+        Issue707.Request result = jsonb.fromJsonStructure(jsonObject, Issue707.Request.class);
+        
+        assertNotNull(result);
+        assertNotNull(result.getId());
+        assertEquals("abc123", result.getId().getValue());
+    }
+    
+    /**
+     * Test for Issue #707: Verify that an integral ID still works correctly.
+     */
+    @Test
+    public void isIntegralNumberWithNumericValue() {
+        // Test with numeric ID - should work without throwing any exception
+        // This test uses fromJsonStructure to exercise JsonStructureToParserAdapter
+        JsonObjectBuilder objectBuilder = jsonProvider.createObjectBuilder();
+        objectBuilder.add("id", 12345);
+        JsonObject jsonObject = objectBuilder.build();
+        
+        YassonJsonb jsonb = (YassonJsonb) JsonbBuilder.create();
+        Issue707.Request result = jsonb.fromJsonStructure(jsonObject, Issue707.Request.class);
+        
+        assertNotNull(result);
+        assertNotNull(result.getId());
+        assertEquals("12345", result.getId().getValue());
+    }
+    
+    /**
+     * Test for Issue #707: Verify that floating point numbers are handled correctly.
+     * isIntegralNumber() should return false for non-integral numbers.
+     * isIntegralNumber() should not throw an exception for floating point numbers.
+     */
+    @Test
+    public void isIntegralNumberWithFloatingPoint() {
+        // Test with floating point ID - isIntegralNumber() returns false,
+        // so the else block handles it as a string
+        // This test uses fromJsonStructure to exercise JsonStructureToParserAdapter
+        JsonObjectBuilder objectBuilder = jsonProvider.createObjectBuilder();
+        objectBuilder.add("id", 123.45);
+        JsonObject jsonObject = objectBuilder.build();
+        
+        YassonJsonb jsonb = (YassonJsonb) JsonbBuilder.create();
+        Issue707.Request result = jsonb.fromJsonStructure(jsonObject, Issue707.Request.class);
+        
+        assertNotNull(result);
+        assertNotNull(result.getId());
+        // The deserializer will read it as a string when isIntegralNumber() returns false
+        assertEquals("123.45", result.getId().getValue());
+    }
 }