Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

missing custom casting #12

Open
sorinpepelea opened this issue Dec 16, 2017 · 12 comments
Open

missing custom casting #12

sorinpepelea opened this issue Dec 16, 2017 · 12 comments

Comments

@sorinpepelea
Copy link

idk if this can be classified as an issue but i have problem casting string to a custom class in automaping
i see no option in automap example to cast string field to customclass
example below
db.select(TEST.class)
.get()
.subscribe(
E -> System.out.println(E.getA())
).dispose();

deffinition of TEST interface :
@query("select '{"X":1, "Y":2}'::json "A";")

public interface TEST {

@Column("A")
    CUSTOMTYPE getA();

}
deffinition of CUSTOMTYPE interface :
public interface CUSTOMTYPE {

@Column("X")
int getX();

@Column("Y")
int getY();

}

@davidmoten
Copy link
Owner

I haven't seen that sort of query before. What type of object does jdbc normally give you? What database?

@davidmoten
Copy link
Owner

FYI, automap just maps resultset columns to obviously transformable types (like BigInteger to long). Looks like you are getting an interesting type back that I'm not familiar with.

@sorinpepelea
Copy link
Author

is postgresql database ..basicaly that query just return a string in json format ..tested and it works ..but i get the error ClassCastException: java.lang.String cannot be cast to CUSTOMTYPE
if i replace CUSTOMTYPE with String ..and gave up CUSTOMTYPE interface ..i get the entire string {"X":1, "Y":2}

@sorinpepelea
Copy link
Author

is there any way i can make automap to use custom converters .. or maybe be able to declare some custom converters ?

@davidmoten
Copy link
Owner

davidmoten commented Dec 17, 2017

Ok then you map to a string value in that class and do another .map to convert the string to a json object using Jackson or whatever. Why would this library be in the business of parsing json?

@davidmoten
Copy link
Owner

Happy to give example if needed

@sorinpepelea
Copy link
Author

cause i happen to already mix json in the process : like this ...
and the json part is working great ..along with your code ..well except the casting prb
i'll be happy if you could give me an example of what you 've just said
public interface TEST {
@JsonProperty("$")
@column("A")
CUSTOMTYPE getA();
}

public interface CUSTOMTYPE {

@JsonProperty("X")
@Column("X")
int getX();

@JsonProperty("Y")
@Column("Y")
int getY();

}

@sorinpepelea
Copy link
Author

Maybe i am out of line here. but it would have been nice if along with annotation would be possible to have custom casting of fields or posibility of declaring and using converters from sql field types to desired object type...

@sorinpepelea
Copy link
Author

something like
@column("A")
@converter(CustomConverter.class)
CUSTOMTYPE getA();

@davidmoten
Copy link
Owner

davidmoten commented Dec 17, 2017 via email

@davidmoten
Copy link
Owner

I've had an initial look and the converter annotation idea is not very attractive because you lose type safety with the annotation (in your example above we can't ensure that CustomConvertor.class actually is a factory for CUSTOMTYPE and we'd need to specify the from class as well in the annotation (again not type checked against CustomConvertor.class).

My suggestion at the moment is you handle your own mapping to the custom types:

@Query("select '{"X":1, "Y":2}'::json "A";")
public interface Holder {
    @Column("A")
    String getA();
}

public static final class Parsed {
    public final int x;
    public final y;
    Parsed(int x, int y) {
      this.x = x;
      this.y = y;
     }
}

//use it
db.select(Holder.class)
  .map(holder -> JsonParser.parse(holder.a()))
  .map(json -> new Parsed(json.getInt("X"), json.getInt("Y")))
  .blockingForEach(System.out::println);

@sorinpepelea
Copy link
Author

thanks
your response time is impressive , i appreciate it.
this should work for now..i am behind schedule anyway.
as suggestion, i was thinking that CustomConvertor.class must encapsulate CUSTOMTYPE rules so that will ensure type safety .Even better, CustomConvertor should implement a DefaultConvertor interface, something like

class CustomConvertor implements DefaultConvertor { ... maping rules from java.sql.type to customtype type}

@interface Convertor {Class value = ...}

public interface TEST {
@column("A")
@convertor(CustomConvertor.class)
String getA();
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants