/*
 * Copyright (c) 2005, 2020 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2005, 2015 SAP. All rights reserved.
 *
 * 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
 */

// Contributors:
//     SAP - initial API and implementation

package org.eclipse.persistence.testing.models.wdf.jpa1.employee;

import jakarta.persistence.Basic;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.TableGenerator;

@Entity
@Table(name = "TMP_HOBBY")
@TableGenerator(name = "StringIdGenerator", table = "TMP_STRING_GEN", pkColumnName = "BEAN_NAME", valueColumnName = "MAX_ID")
public class Hobby {
    private String id;
    private String description;
    private String category;

    public Hobby() {
    }

    public Hobby(String aDescription) {
        description = aDescription;
    }

    public Hobby(String txt, String aDescription) {
        id = txt;
        description = aDescription;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "StringIdGenerator")
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @Basic
    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @Basic
    public String getCategory() {
        return category;
    }

    public void setCategory(final String aCategory) {
        category = aCategory;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (!(obj instanceof Hobby)) {
            return false;
        }
        final Hobby other = (Hobby) obj;

        if (id == null && other.id != null) {
            return false;
        }
        if (id != null && !id.equals(other.id)) {
            return false;
        }
        if (description == null && other.description != null) {
            return false;
        }
        if (description != null && !description.equals(other.description)) {
            return false;
        }
        if (category != null && !category.equals(other.category)) {
            return false;
        }
        if (category == null && other.category != null) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int result = 17 + id.hashCode();
        result *= 37;
        if (description != null) {
            result += description.hashCode();
        }
        result += 17;
        result *= 37;
        if (category != null) {
            result += category.hashCode();
        }

        return result;
    }

    @Override
    public String toString() {
        return id + ":" + category + ":" + description;
    }
}
