Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nested java bean used in Spark SQL

Tags:

apache-spark

I am using Spark 2.1, and want to write a Person list as a dataframe. Person class has a nested java bean class Address

Person:

public class Person {
    private String name;
    private Address address;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }
}

Address:

public class Address {
    private String city;
    private String street;

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }
}

I am using following code to create a dataframe against List[Person]

import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.SparkSession;

import java.util.ArrayList;
import java.util.List;

public class PersonTest {
    public static void main(String[] args) {
        Person p = new Person();
        p.setName("Tom");
        Address address = new Address();
        address.setCity("C");
        address.setStreet("001");
        p.setAddress(address);
        List<Person> persons = new ArrayList<Person>();
        persons.add(p);

        SparkSession session = SparkSession.builder().master("local").appName("abc").enableHiveSupport().getOrCreate();

        Dataset<Row> df = session.createDataFrame(persons, Person.class);
        df.printSchema();

        df.write().json("file:///D:/applog/spark/" + System.currentTimeMillis());

    }
}

But exception occurs as follows, I would ask how to fix this issue.

Exception in thread "main" scala.MatchError: com.Address@1e5eb20a (of class com..Address)
    at org.apache.spark.sql.catalyst.CatalystTypeConverters$StructConverter.toCatalystImpl(CatalystTypeConverters.scala:236)
    at org.apache.spark.sql.catalyst.CatalystTypeConverters$StructConverter.toCatalystImpl(CatalystTypeConverters.scala:231)
    at org.apache.spark.sql.catalyst.CatalystTypeConverters$CatalystTypeConverter.toCatalyst(CatalystTypeConverters.scala:103)
    at org.apache.spark.sql.catalyst.CatalystTypeConverters$$anonfun$createToCatalystConverter$2.apply(CatalystTypeConverters.scala:383)
    at org.apache.spark.sql.SQLContext$$anonfun$beansToRows$1$$anonfun$apply$1.apply(SQLContext.scala:1113)
    at org.apache.spark.sql.SQLContext$$anonfun$beansToRows$1$$anonfun$apply$1.apply(SQLContext.scala:1113)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234)
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234)
    at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33)
    at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:186)
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:234)
    at scala.collection.mutable.ArrayOps$ofRef.map(ArrayOps.scala:186)
    at org.apache.spark.sql.SQLContext$$anonfun$beansToRows$1.apply(SQLContext.scala:1113)
    at org.apache.spark.sql.SQLContext$$anonfun$beansToRows$1.apply(SQLContext.scala:1111)
    at scala.collection.Iterator$$anon$11.next(Iterator.scala:409)
    at scala.collection.Iterator$class.toStream(Iterator.scala:1322)
    at scala.collection.AbstractIterator.toStream(Iterator.scala:1336)
    at scala.collection.TraversableOnce$class.toSeq(TraversableOnce.scala:298)
    at scala.collection.AbstractIterator.toSeq(Iterator.scala:1336)
    at org.apache.spark.sql.SparkSession.createDataFrame(SparkSession.scala:380)
like image 585
Tom Avatar asked Dec 17 '25 20:12

Tom


1 Answers

You can create a typed Dataset instead, then convert that to a Dataframe if needed:

Dataset<Person> ds = session.createDataset(persons, Encoders.bean(Person.class));
Dataset<Row> df = ds.toDF();
like image 200
zman0900 Avatar answered Dec 20 '25 14:12

zman0900



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!